summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2019-09-30 13:46:19 +0200
committerGitHub <noreply@github.com>2019-09-30 13:46:19 +0200
commit9898a2fb3441e7382dba4190233f466b8271deae (patch)
tree9629a5ce665db95addf0d0bc0f46864ef71b5a49 /lib
parentMerge pull request #5066 from ak503/libfrr_crash (diff)
parentlib: delete interface if you can in upper level protocol (diff)
downloadfrr-9898a2fb3441e7382dba4190233f466b8271deae.tar.xz
frr-9898a2fb3441e7382dba4190233f466b8271deae.zip
Merge pull request #5009 from donaldsharp/interface_deletion
lib, zebra: Allow for interface deletion when kernel event happens
Diffstat (limited to 'lib')
-rw-r--r--lib/if.c50
-rw-r--r--lib/if.h16
-rw-r--r--lib/zclient.c72
-rw-r--r--lib/zclient.h6
4 files changed, 120 insertions, 24 deletions
diff --git a/lib/if.c b/lib/if.c
index fbab0004f..f2b45512d 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -58,6 +58,13 @@ DEFINE_QOBJ_TYPE(interface)
DEFINE_HOOK(if_add, (struct interface * ifp), (ifp))
DEFINE_KOOH(if_del, (struct interface * ifp), (ifp))
+struct interface_master{
+ int (*create_hook)(struct interface *ifp);
+ int (*up_hook)(struct interface *ifp);
+ int (*down_hook)(struct interface *ifp);
+ int (*destroy_hook)(struct interface *ifp);
+} ifp_master = { 0, };
+
/* Compare interface names, returning an integer greater than, equal to, or
* less than 0, (following the strcmp convention), according to the
* relationship between ifp1 and ifp2. Interface names consist of an
@@ -168,6 +175,34 @@ static struct interface *if_create_backend(const char *name, ifindex_t ifindex,
return ifp;
}
+void if_new_via_zapi(struct interface *ifp)
+{
+ if (ifp_master.create_hook)
+ (*ifp_master.create_hook)(ifp);
+}
+
+void if_destroy_via_zapi(struct interface *ifp)
+{
+ if (ifp_master.destroy_hook)
+ (*ifp_master.destroy_hook)(ifp);
+
+ if_set_index(ifp, IFINDEX_INTERNAL);
+ if (!ifp->configured)
+ if_delete(ifp);
+}
+
+void if_up_via_zapi(struct interface *ifp)
+{
+ if (ifp_master.up_hook)
+ (*ifp_master.up_hook)(ifp);
+}
+
+void if_down_via_zapi(struct interface *ifp)
+{
+ if (ifp_master.down_hook)
+ (*ifp_master.down_hook)(ifp);
+}
+
struct interface *if_create(const char *name, vrf_id_t vrf_id)
{
return if_create_backend(name, IFINDEX_INTERNAL, vrf_id);
@@ -1367,6 +1402,17 @@ void if_cmd_init(void)
install_element(INTERFACE_NODE, &no_interface_desc_cmd);
}
+void if_zapi_callbacks(int (*create)(struct interface *ifp),
+ int (*up)(struct interface *ifp),
+ int (*down)(struct interface *ifp),
+ int (*destroy)(struct interface *ifp))
+{
+ ifp_master.create_hook = create;
+ ifp_master.up_hook = up;
+ ifp_master.down_hook = down;
+ ifp_master.destroy_hook = destroy;
+}
+
/* ------- Northbound callbacks ------- */
/*
@@ -1423,6 +1469,8 @@ static int lib_interface_create(enum nb_event event,
#else
ifp = if_get_by_name(ifname, vrf->vrf_id);
#endif /* SUNOS_5 */
+
+ ifp->configured = true;
nb_running_set_entry(dnode, ifp);
break;
}
@@ -1450,6 +1498,8 @@ static int lib_interface_destroy(enum nb_event event,
break;
case NB_EV_APPLY:
ifp = nb_running_unset_entry(dnode);
+
+ ifp->configured = false;
if_delete(ifp);
break;
}
diff --git a/lib/if.h b/lib/if.h
index e3ec278f9..a3c6e9ff5 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -293,6 +293,12 @@ struct interface {
struct route_node *node;
vrf_id_t vrf_id;
+ /*
+ * Has the end users entered `interface XXXX` from the cli in some
+ * fashion?
+ */
+ bool configured;
+
QOBJ_FIELDS
};
@@ -552,6 +558,16 @@ void if_link_params_free(struct interface *);
/* Northbound. */
extern void if_cmd_init(void);
+extern void if_zapi_callbacks(int (*create)(struct interface *ifp),
+ int (*up)(struct interface *ifp),
+ int (*down)(struct interface *ifp),
+ int (*destroy)(struct interface *ifp));
+
+extern void if_new_via_zapi(struct interface *ifp);
+extern void if_up_via_zapi(struct interface *ifp);
+extern void if_down_via_zapi(struct interface *ifp);
+extern void if_destroy_via_zapi(struct interface *ifp);
+
extern const struct frr_yang_module_info frr_interface_info;
#ifdef __cplusplus
diff --git a/lib/zclient.c b/lib/zclient.c
index 92a495ac6..912946668 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -49,6 +49,9 @@ enum event { ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT };
/* Prototype for event manager. */
static void zclient_event(enum event, struct zclient *);
+static void zebra_interface_if_set_value(struct stream *s,
+ struct interface *ifp);
+
struct zclient_options zclient_options_default = {.receive_notify = false};
struct sockaddr_storage zclient_addr;
@@ -1547,10 +1550,11 @@ static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
vrf_delete(vrf);
}
-struct interface *zebra_interface_add_read(struct stream *s, vrf_id_t vrf_id)
+static void zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
{
struct interface *ifp;
char ifname_tmp[INTERFACE_NAMSIZ];
+ struct stream *s = zclient->ibuf;
/* Read interface name. */
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
@@ -1560,15 +1564,14 @@ struct interface *zebra_interface_add_read(struct stream *s, vrf_id_t vrf_id)
zebra_interface_if_set_value(s, ifp);
- return ifp;
+ if_new_via_zapi(ifp);
}
/*
* Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
* from zebra server. The format of this message is the same as
- * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
- * comments for zebra_interface_add_read), except that no sockaddr_dl
- * is sent at the tail of the message.
+ * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE,
+ * except that no sockaddr_dl is sent at the tail of the message.
*/
struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
{
@@ -1592,6 +1595,46 @@ struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
return ifp;
}
+static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+ struct stream *s = zclient->ibuf;
+
+ ifp = zebra_interface_state_read(s, vrf_id);
+
+ if (ifp == NULL)
+ return;
+
+ if_destroy_via_zapi(ifp);
+ return;
+}
+
+static void zclient_interface_up(struct zclient *zclient, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+ struct stream *s = zclient->ibuf;
+
+ ifp = zebra_interface_state_read(s, vrf_id);
+
+ if (!ifp)
+ return;
+
+ if_up_via_zapi(ifp);
+}
+
+static void zclient_interface_down(struct zclient *zclient, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+ struct stream *s = zclient->ibuf;
+
+ ifp = zebra_interface_state_read(s, vrf_id);
+
+ if (!ifp)
+ return;
+
+ if_down_via_zapi(ifp);
+}
+
static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
{
@@ -1656,7 +1699,8 @@ struct interface *zebra_interface_link_params_read(struct stream *s,
return ifp;
}
-void zebra_interface_if_set_value(struct stream *s, struct interface *ifp)
+static void zebra_interface_if_set_value(struct stream *s,
+ struct interface *ifp)
{
uint8_t link_params_status = 0;
ifindex_t old_ifindex;
@@ -2789,14 +2833,10 @@ static int zclient_read(struct thread *thread)
zclient_vrf_delete(zclient, vrf_id);
break;
case ZEBRA_INTERFACE_ADD:
- if (zclient->interface_add)
- (*zclient->interface_add)(command, zclient, length,
- vrf_id);
+ zclient_interface_add(zclient, vrf_id);
break;
case ZEBRA_INTERFACE_DELETE:
- if (zclient->interface_delete)
- (*zclient->interface_delete)(command, zclient, length,
- vrf_id);
+ zclient_interface_delete(zclient, vrf_id);
break;
case ZEBRA_INTERFACE_ADDRESS_ADD:
if (zclient->interface_address_add)
@@ -2824,14 +2864,10 @@ static int zclient_read(struct thread *thread)
command, zclient, length, vrf_id);
break;
case ZEBRA_INTERFACE_UP:
- if (zclient->interface_up)
- (*zclient->interface_up)(command, zclient, length,
- vrf_id);
+ zclient_interface_up(zclient, vrf_id);
break;
case ZEBRA_INTERFACE_DOWN:
- if (zclient->interface_down)
- (*zclient->interface_down)(command, zclient, length,
- vrf_id);
+ zclient_interface_down(zclient, vrf_id);
break;
case ZEBRA_INTERFACE_VRF_UPDATE:
if (zclient->interface_vrf_update)
diff --git a/lib/zclient.h b/lib/zclient.h
index eb3c97b11..5f9edc36f 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -240,10 +240,6 @@ struct zclient {
void (*zebra_connected)(struct zclient *);
void (*zebra_capabilities)(struct zclient_capabilities *cap);
int (*router_id_update)(ZAPI_CALLBACK_ARGS);
- int (*interface_add)(ZAPI_CALLBACK_ARGS);
- int (*interface_delete)(ZAPI_CALLBACK_ARGS);
- int (*interface_up)(ZAPI_CALLBACK_ARGS);
- int (*interface_down)(ZAPI_CALLBACK_ARGS);
int (*interface_address_add)(ZAPI_CALLBACK_ARGS);
int (*interface_address_delete)(ZAPI_CALLBACK_ARGS);
int (*interface_link_params)(ZAPI_CALLBACK_ARGS);
@@ -617,7 +613,6 @@ extern bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr);
extern void zclient_interface_set_master(struct zclient *client,
struct interface *master,
struct interface *slave);
-extern struct interface *zebra_interface_add_read(struct stream *, vrf_id_t);
extern struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t);
extern struct connected *zebra_interface_address_read(int, struct stream *,
vrf_id_t);
@@ -626,7 +621,6 @@ zebra_interface_nbr_address_read(int, struct stream *, vrf_id_t);
extern struct interface *zebra_interface_vrf_update_read(struct stream *s,
vrf_id_t vrf_id,
vrf_id_t *new_vrf_id);
-extern void zebra_interface_if_set_value(struct stream *, struct interface *);
extern void zebra_router_id_update_read(struct stream *s, struct prefix *rid);
extern struct interface *zebra_interface_link_params_read(struct stream *s,