summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2021-03-11 16:01:10 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2021-04-30 10:33:18 +0200
commitdb51f0cd10709079c73b68e6abe9bed0785f2137 (patch)
tree7c3b27b656443c5c036fee8f6a4d1c4e141b8597
parentzebra: new dplane action to set gre link interface (diff)
downloadfrr-db51f0cd10709079c73b68e6abe9bed0785f2137.tar.xz
frr-db51f0cd10709079c73b68e6abe9bed0785f2137.zip
nhrp: Preserve mtu during interface up/down and tunnel source change
preserve mtu upon interface flapping and tunnel source change. Signed-off-by:Reuben Dowle <reuben.dowle@4rf.com> Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
-rw-r--r--nhrpd/nhrp_route.c1
-rw-r--r--zebra/if_netlink.c5
-rw-r--r--zebra/zapi_msg.c11
-rw-r--r--zebra/zebra_dplane.c13
-rw-r--r--zebra/zebra_dplane.h5
5 files changed, 30 insertions, 5 deletions
diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c
index 1f513b7c0..ee8db277d 100644
--- a/nhrpd/nhrp_route.c
+++ b/nhrpd/nhrp_route.c
@@ -435,6 +435,7 @@ void nhrp_send_zebra_gre_source_set(struct interface *ifp,
stream_putl(s, ifp->ifindex);
stream_putl(s, link_idx);
stream_putl(s, link_vrf_id);
+ stream_putl(s, 0); /* mtu provisioning */
stream_putw_at(s, 0, stream_get_endp(s));
zclient_send_message(zclient);
}
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 44ee8d946..1886f7a54 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -473,6 +473,7 @@ netlink_gre_set_msg_encoder(struct zebra_dplane_ctx *ctx, void *buf,
char buf[];
} *req = buf;
uint32_t link_idx;
+ unsigned int mtu;
struct rtattr *rta_info, *rta_data;
if (buflen < sizeof(*req))
@@ -486,6 +487,10 @@ netlink_gre_set_msg_encoder(struct zebra_dplane_ctx *ctx, void *buf,
req->ifi.ifi_index = dplane_ctx_get_ifindex(ctx);
req->ifi.ifi_change = 0xFFFFFFFF;
link_idx = dplane_ctx_gre_get_link_ifindex(ctx);
+ mtu = dplane_ctx_gre_get_mtu(ctx);
+
+ if (mtu && !nl_attr_put32(&req->n, buflen, IFLA_MTU, mtu))
+ return 0;
rta_info = nl_attr_nest(&req->n, buflen, IFLA_LINKINFO);
if (!rta_info)
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 22a6bf496..75e2f59b9 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -3438,12 +3438,14 @@ static inline void zebra_gre_source_set(ZAPI_HANDLER_ARGS)
vrf_id_t vrf_id = zvrf->vrf->vrf_id;
struct zebra_if *zif, *gre_zif;
struct zebra_l2info_gre *gre_info;
+ unsigned int mtu;
s = msg;
STREAM_GETL(s, idx);
ifp = if_lookup_by_index(idx, vrf_id);
STREAM_GETL(s, link_idx);
STREAM_GETL(s, link_vrf_id);
+ STREAM_GETL(s, mtu);
ifp_link = if_lookup_by_index(link_idx, link_vrf_id);
if (!ifp_link || !ifp) {
@@ -3464,11 +3466,14 @@ static inline void zebra_gre_source_set(ZAPI_HANDLER_ARGS)
if (!gre_info)
return;
- /* if gre link already set */
- if (gre_zif->link && gre_zif->link == ifp_link)
+ if (!mtu)
+ mtu = ifp->mtu;
+
+ /* if gre link already set or mtu did not change, do not set it */
+ if (gre_zif->link && gre_zif->link == ifp_link && mtu == ifp->mtu)
return;
- dplane_gre_set(ifp, ifp_link);
+ dplane_gre_set(ifp, ifp_link, mtu);
stream_failure:
return;
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 565ab821d..b54973a94 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -273,6 +273,7 @@ struct dplane_rule_info {
struct dplane_gre_ctx {
uint32_t link_ifindex;
+ unsigned int mtu;
};
/*
* The context block used to exchange info about route updates across
@@ -1795,6 +1796,14 @@ dplane_ctx_gre_get_link_ifindex(const struct zebra_dplane_ctx *ctx)
return ctx->u.gre.link_ifindex;
}
+unsigned int
+dplane_ctx_gre_get_mtu(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.gre.mtu;
+}
+
/* Accessors for PBR rule information */
int dplane_ctx_rule_get_sock(const struct zebra_dplane_ctx *ctx)
{
@@ -4152,7 +4161,7 @@ dplane_pbr_ipset_entry_delete(struct zebra_pbr_ipset_entry *ipset)
* Common helper api for GRE set
*/
enum zebra_dplane_result
-dplane_gre_set(struct interface *ifp, struct interface *ifp_link)
+dplane_gre_set(struct interface *ifp, struct interface *ifp_link, unsigned int mtu)
{
enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
struct zebra_dplane_ctx *ctx;
@@ -4187,6 +4196,8 @@ dplane_gre_set(struct interface *ifp, struct interface *ifp_link)
else
ctx->u.gre.link_ifindex = 0;
+ ctx->u.gre.mtu = mtu;
+
ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
/* Enqueue context for processing */
diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h
index 5df58e6e9..5405a7cb8 100644
--- a/zebra/zebra_dplane.h
+++ b/zebra/zebra_dplane.h
@@ -531,6 +531,8 @@ dplane_ctx_neightable_get_ucast_probes(const struct zebra_dplane_ctx *ctx);
/* Accessor for GRE set */
uint32_t
dplane_ctx_gre_get_link_ifindex(const struct zebra_dplane_ctx *ctx);
+unsigned int
+dplane_ctx_gre_get_mtu(const struct zebra_dplane_ctx *ctx);
/* Namespace info - esp. for netlink communication */
const struct zebra_dplane_info *dplane_ctx_get_ns(
@@ -704,7 +706,8 @@ enum zebra_dplane_result dplane_neigh_table_update(const struct interface *ifp,
* Enqueue a GRE set
*/
enum zebra_dplane_result
-dplane_gre_set(struct interface *ifp, struct interface *ifp_link);
+dplane_gre_set(struct interface *ifp, struct interface *ifp_link,
+ unsigned int mtu);
/* Forward ref of zebra_pbr_rule */
struct zebra_pbr_rule;