diff options
| author | David Lamparter <equinox@opensourcerouting.org> | 2017-08-06 08:57:42 +0200 | 
|---|---|---|
| committer | David Lamparter <equinox@opensourcerouting.org> | 2017-08-15 13:26:03 +0200 | 
| commit | ead4ee99acd63d2342e9e9dda7a8f5a103a6f550 (patch) | |
| tree | 876fee1047023d8571c9a75af9cc371c738e4e75 | |
| parent | 2eb27eecf011a06c01e58a735d8bf087d7519979 (diff) | |
zebra: irdp: manage separate IRDP struct
This allocates the per-interface IRDP data as needed; so the pointer in
zebra_if is now really opaque.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
| -rw-r--r-- | zebra/irdp_interface.c | 117 | ||||
| -rw-r--r-- | zebra/irdp_main.c | 25 | ||||
| -rw-r--r-- | zebra/irdp_packet.c | 4 | 
3 files changed, 75 insertions, 71 deletions
diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index 032090adf2..3465bdebbf 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -63,6 +63,25 @@  extern int irdp_sock; +DEFINE_MTYPE_STATIC(ZEBRA, IRDP_IF, "IRDP interface data") + +static struct irdp_interface *irdp_if_get(struct interface *ifp) +{ +	struct zebra_if *zi = ifp->info; +	if (!zi->irdp) +		zi->irdp = XCALLOC(MTYPE_IRDP_IF, sizeof(*zi->irdp)); +	return zi->irdp; +} + +static int irdp_if_delete(struct interface *ifp) +{ +	struct zebra_if *zi = ifp->info; +	if (!zi) +		return 0; +	XFREE(MTYPE_IRDP_IF, zi->irdp); +	return 0; +} +  static const char *inet_2a(u_int32_t a, char *b)  {  	sprintf(b, "%u.%u.%u.%u", (a)&0xFF, (a >> 8) & 0xFF, (a >> 16) & 0xFF, @@ -117,10 +136,13 @@ static int if_group(struct interface *ifp, int sock, u_int32_t group,  static int if_add_group(struct interface *ifp)  {  	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; +	struct irdp_interface *irdp = zi->irdp;  	int ret;  	char b1[INET_ADDRSTRLEN]; +	if (!irdp) +		return -1; +  	ret = if_group(ifp, irdp_sock, INADDR_ALLRTRS_GROUP, IP_ADD_MEMBERSHIP);  	if (ret < 0) {  		return ret; @@ -135,10 +157,13 @@ static int if_add_group(struct interface *ifp)  static int if_drop_group(struct interface *ifp)  {  	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; +	struct irdp_interface *irdp = zi->irdp;  	int ret;  	char b1[INET_ADDRSTRLEN]; +	if (!irdp) +		return -1; +  	ret = if_group(ifp, irdp_sock, INADDR_ALLRTRS_GROUP,  		       IP_DROP_MEMBERSHIP);  	if (ret < 0) @@ -150,11 +175,8 @@ static int if_drop_group(struct interface *ifp)  	return 0;  } -static void if_set_defaults(struct interface *ifp) +static void if_set_defaults(struct irdp_interface *irdp)  { -	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; -  	irdp->MaxAdvertInterval = IRDP_MAXADVERTINTERVAL;  	irdp->MinAdvertInterval = IRDP_MINADVERTINTERVAL;  	irdp->Preference = IRDP_PREFERENCE; @@ -176,11 +198,13 @@ static void irdp_if_start(struct interface *ifp, int multicast,  			  int set_defaults)  {  	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; +	struct irdp_interface *irdp = zi->irdp;  	struct listnode *node;  	struct connected *ifc;  	u_int32_t timer, seed; +	assert(irdp); +  	if (irdp->flags & IF_ACTIVE) {  		zlog_warn("IRDP: Interface is already active %s", ifp->name);  		return; @@ -215,7 +239,7 @@ static void irdp_if_start(struct interface *ifp, int multicast,  	}  	if (set_defaults) -		if_set_defaults(ifp); +		if_set_defaults(irdp);  	irdp->irdp_sent = 0; @@ -254,7 +278,7 @@ static void irdp_if_start(struct interface *ifp, int multicast,  static void irdp_if_stop(struct interface *ifp)  {  	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; +	struct irdp_interface *irdp = zi->irdp;  	if (irdp == NULL) {  		zlog_warn("Interface %s structure is NULL", ifp->name); @@ -281,8 +305,10 @@ static void irdp_if_stop(struct interface *ifp)  static void irdp_if_shutdown(struct interface *ifp)  {  	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; +	struct irdp_interface *irdp = zi->irdp; +	if (!irdp) +		return;  	if (irdp->flags & IF_SHUTDOWN) {  		zlog_warn("IRDP: Interface is already shutdown %s", ifp->name);  		return; @@ -300,8 +326,7 @@ static void irdp_if_shutdown(struct interface *ifp)  static void irdp_if_no_shutdown(struct interface *ifp)  { -	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; +	struct irdp_interface *irdp = irdp_if_get(ifp);  	if (!(irdp->flags & IF_SHUTDOWN)) {  		zlog_warn("IRDP: Interface is not shutdown %s", ifp->name); @@ -319,11 +344,14 @@ static void irdp_if_no_shutdown(struct interface *ifp)  int irdp_config_write(struct vty *vty, struct interface *ifp)  {  	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; +	struct irdp_interface *irdp = zi->irdp;  	struct Adv *adv;  	struct listnode *node;  	char b1[INET_ADDRSTRLEN]; +	if (!irdp) +		return 0; +  	if (irdp->flags & IF_ACTIVE || irdp->flags & IF_SHUTDOWN) {  		if (irdp->flags & IF_SHUTDOWN) @@ -360,6 +388,7 @@ DEFUN (ip_irdp_multicast,         "Use multicast mode\n")  {  	VTY_DECLVAR_CONTEXT(interface, ifp); +	irdp_if_get(ifp);  	irdp_if_start(ifp, TRUE, TRUE);  	return CMD_SUCCESS; @@ -373,6 +402,7 @@ DEFUN (ip_irdp_broadcast,         "Use broadcast mode\n")  {  	VTY_DECLVAR_CONTEXT(interface, ifp); +	irdp_if_get(ifp);  	irdp_if_start(ifp, FALSE, TRUE);  	return CMD_SUCCESS; @@ -428,11 +458,7 @@ DEFUN (ip_irdp_holdtime,  {  	int idx_number = 3;  	VTY_DECLVAR_CONTEXT(interface, ifp); -	struct zebra_if *zi; -	struct irdp_interface *irdp; - -	zi = ifp->info; -	irdp = &zi->irdp; +	struct irdp_interface *irdp = irdp_if_get(ifp);  	irdp->Lifetime = atoi(argv[idx_number]->arg);  	return CMD_SUCCESS; @@ -448,11 +474,7 @@ DEFUN (ip_irdp_minadvertinterval,  {  	int idx_number = 3;  	VTY_DECLVAR_CONTEXT(interface, ifp); -	struct zebra_if *zi; -	struct irdp_interface *irdp; - -	zi = ifp->info; -	irdp = &zi->irdp; +	struct irdp_interface *irdp = irdp_if_get(ifp);  	if ((unsigned)atoi(argv[idx_number]->arg) <= irdp->MaxAdvertInterval) {  		irdp->MinAdvertInterval = atoi(argv[idx_number]->arg); @@ -475,11 +497,7 @@ DEFUN (ip_irdp_maxadvertinterval,  {  	int idx_number = 3;  	VTY_DECLVAR_CONTEXT(interface, ifp); -	struct zebra_if *zi; -	struct irdp_interface *irdp; - -	zi = ifp->info; -	irdp = &zi->irdp; +	struct irdp_interface *irdp = irdp_if_get(ifp);  	if (irdp->MinAdvertInterval <= (unsigned)atoi(argv[idx_number]->arg)) {  		irdp->MaxAdvertInterval = atoi(argv[idx_number]->arg); @@ -507,11 +525,7 @@ DEFUN (ip_irdp_preference,  {  	int idx_number = 3;  	VTY_DECLVAR_CONTEXT(interface, ifp); -	struct zebra_if *zi; -	struct irdp_interface *irdp; - -	zi = ifp->info; -	irdp = &zi->irdp; +	struct irdp_interface *irdp = irdp_if_get(ifp);  	irdp->Preference = atoi(argv[idx_number]->arg);  	return CMD_SUCCESS; @@ -530,17 +544,13 @@ DEFUN (ip_irdp_address_preference,  	int idx_ipv4 = 3;  	int idx_number = 5;  	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct irdp_interface *irdp = irdp_if_get(ifp);  	struct listnode *node;  	struct in_addr ip;  	int pref;  	int ret; -	struct zebra_if *zi; -	struct irdp_interface *irdp;  	struct Adv *adv; -	zi = ifp->info; -	irdp = &zi->irdp; -  	ret = inet_aton(argv[idx_ipv4]->arg, &ip);  	if (!ret)  		return CMD_WARNING_CONFIG_FAILED; @@ -572,16 +582,12 @@ DEFUN (no_ip_irdp_address_preference,  {  	int idx_ipv4 = 4;  	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct irdp_interface *irdp = irdp_if_get(ifp);  	struct listnode *node, *nnode;  	struct in_addr ip;  	int ret; -	struct zebra_if *zi; -	struct irdp_interface *irdp;  	struct Adv *adv; -	zi = ifp->info; -	irdp = &zi->irdp; -  	ret = inet_aton(argv[idx_ipv4]->arg, &ip);  	if (!ret)  		return CMD_WARNING_CONFIG_FAILED; @@ -605,11 +611,7 @@ DEFUN (ip_irdp_debug_messages,         "Enable debugging for IRDP messages\n")  {  	VTY_DECLVAR_CONTEXT(interface, ifp); -	struct zebra_if *zi; -	struct irdp_interface *irdp; - -	zi = ifp->info; -	irdp = &zi->irdp; +	struct irdp_interface *irdp = irdp_if_get(ifp);  	irdp->flags |= IF_DEBUG_MESSAGES; @@ -625,11 +627,7 @@ DEFUN (ip_irdp_debug_misc,         "Enable debugging for miscellaneous IRDP events\n")  {  	VTY_DECLVAR_CONTEXT(interface, ifp); -	struct zebra_if *zi; -	struct irdp_interface *irdp; - -	zi = ifp->info; -	irdp = &zi->irdp; +	struct irdp_interface *irdp = irdp_if_get(ifp);  	irdp->flags |= IF_DEBUG_MISC; @@ -645,11 +643,7 @@ DEFUN (ip_irdp_debug_packet,         "Enable debugging for IRDP packets\n")  {  	VTY_DECLVAR_CONTEXT(interface, ifp); -	struct zebra_if *zi; -	struct irdp_interface *irdp; - -	zi = ifp->info; -	irdp = &zi->irdp; +	struct irdp_interface *irdp = irdp_if_get(ifp);  	irdp->flags |= IF_DEBUG_PACKET; @@ -666,11 +660,7 @@ DEFUN (ip_irdp_debug_disable,         "Disable debugging for all IRDP events\n")  {  	VTY_DECLVAR_CONTEXT(interface, ifp); -	struct zebra_if *zi; -	struct irdp_interface *irdp; - -	zi = ifp->info; -	irdp = &zi->irdp; +	struct irdp_interface *irdp = irdp_if_get(ifp);  	irdp->flags &= ~IF_DEBUG_PACKET;  	irdp->flags &= ~IF_DEBUG_MESSAGES; @@ -682,6 +672,7 @@ DEFUN (ip_irdp_debug_disable,  void irdp_if_init()  {  	hook_register(zebra_if_config_wr, irdp_config_write); +	hook_register(if_del, irdp_if_delete);  	install_element(INTERFACE_NODE, &ip_irdp_broadcast_cmd);  	install_element(INTERFACE_NODE, &ip_irdp_multicast_cmd); diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index e463608af1..73c6d8141a 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -52,6 +52,7 @@  #include "zclient.h"  #include "thread.h"  #include "privs.h" +#include "libfrr.h"  #include "zebra/interface.h"  #include "zebra/rtadv.h"  #include "zebra/rib.h" @@ -143,7 +144,7 @@ static int make_advertisement_packet(struct interface *ifp, struct prefix *p,  				     struct stream *s)  {  	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; +	struct irdp_interface *irdp = zi->irdp;  	int size;  	int pref;  	u_int16_t checksum; @@ -175,11 +176,13 @@ static int make_advertisement_packet(struct interface *ifp, struct prefix *p,  static void irdp_send(struct interface *ifp, struct prefix *p, struct stream *s)  {  	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; +	struct irdp_interface *irdp = zi->irdp;  	char buf[PREFIX_STRLEN];  	u_int32_t dst;  	u_int32_t ttl = 1; +	if (!irdp) +		return;  	if (!(ifp->flags & IFF_UP))  		return; @@ -211,11 +214,14 @@ int irdp_send_thread(struct thread *t_advert)  	u_int32_t timer, tmp;  	struct interface *ifp = THREAD_ARG(t_advert);  	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; +	struct irdp_interface *irdp = zi->irdp;  	struct prefix *p;  	struct listnode *node, *nnode;  	struct connected *ifc; +	if (!irdp) +		return 0; +  	irdp->flags &= ~IF_SOLICIT;  	if (ifp->connected) @@ -250,12 +256,15 @@ int irdp_send_thread(struct thread *t_advert)  void irdp_advert_off(struct interface *ifp)  {  	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; +	struct irdp_interface *irdp = zi->irdp;  	struct listnode *node, *nnode;  	int i;  	struct connected *ifc;  	struct prefix *p; +	if (!irdp) +		return; +  	if (irdp->t_advertise)  		thread_cancel(irdp->t_advertise);  	irdp->t_advertise = NULL; @@ -279,9 +288,12 @@ void irdp_advert_off(struct interface *ifp)  void process_solicit(struct interface *ifp)  {  	struct zebra_if *zi = ifp->info; -	struct irdp_interface *irdp = &zi->irdp; +	struct irdp_interface *irdp = zi->irdp;  	u_int32_t timer; +	if (!irdp) +		return; +  	/* When SOLICIT is active we reject further incoming solicits  	   this keeps down the answering rate so we don't have think  	   about DoS attacks here. */ @@ -317,7 +329,7 @@ static int irdp_finish(void)  		if (!zi)  			continue; -		irdp = &zi->irdp; +		irdp = zi->irdp;  		if (!irdp)  			continue; @@ -326,6 +338,7 @@ static int irdp_finish(void)  			irdp_advert_off(ifp);  		}  	} +	return 0;  }  void irdp_init(void) diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c index 3bd093d97b..a64eac2ea4 100644 --- a/zebra/irdp_packet.c +++ b/zebra/irdp_packet.c @@ -84,7 +84,7 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp)  	if (!zi)  		return; -	irdp = &zi->irdp; +	irdp = zi->irdp;  	if (!irdp)  		return; @@ -240,7 +240,7 @@ int irdp_read_raw(struct thread *r)  	if (!zi)  		return ret; -	irdp = &zi->irdp; +	irdp = zi->irdp;  	if (!irdp)  		return ret;  | 
