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>
This commit is contained in:
David Lamparter 2017-08-06 08:57:42 +02:00
parent 2eb27eecf0
commit ead4ee99ac
3 changed files with 75 additions and 71 deletions

View File

@ -63,6 +63,25 @@
extern int irdp_sock; 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) 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, 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) static int if_add_group(struct interface *ifp)
{ {
struct zebra_if *zi = ifp->info; struct zebra_if *zi = ifp->info;
struct irdp_interface *irdp = &zi->irdp; struct irdp_interface *irdp = zi->irdp;
int ret; int ret;
char b1[INET_ADDRSTRLEN]; char b1[INET_ADDRSTRLEN];
if (!irdp)
return -1;
ret = if_group(ifp, irdp_sock, INADDR_ALLRTRS_GROUP, IP_ADD_MEMBERSHIP); ret = if_group(ifp, irdp_sock, INADDR_ALLRTRS_GROUP, IP_ADD_MEMBERSHIP);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
@ -135,10 +157,13 @@ static int if_add_group(struct interface *ifp)
static int if_drop_group(struct interface *ifp) static int if_drop_group(struct interface *ifp)
{ {
struct zebra_if *zi = ifp->info; struct zebra_if *zi = ifp->info;
struct irdp_interface *irdp = &zi->irdp; struct irdp_interface *irdp = zi->irdp;
int ret; int ret;
char b1[INET_ADDRSTRLEN]; char b1[INET_ADDRSTRLEN];
if (!irdp)
return -1;
ret = if_group(ifp, irdp_sock, INADDR_ALLRTRS_GROUP, ret = if_group(ifp, irdp_sock, INADDR_ALLRTRS_GROUP,
IP_DROP_MEMBERSHIP); IP_DROP_MEMBERSHIP);
if (ret < 0) if (ret < 0)
@ -150,11 +175,8 @@ static int if_drop_group(struct interface *ifp)
return 0; 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->MaxAdvertInterval = IRDP_MAXADVERTINTERVAL;
irdp->MinAdvertInterval = IRDP_MINADVERTINTERVAL; irdp->MinAdvertInterval = IRDP_MINADVERTINTERVAL;
irdp->Preference = IRDP_PREFERENCE; irdp->Preference = IRDP_PREFERENCE;
@ -176,11 +198,13 @@ static void irdp_if_start(struct interface *ifp, int multicast,
int set_defaults) int set_defaults)
{ {
struct zebra_if *zi = ifp->info; struct zebra_if *zi = ifp->info;
struct irdp_interface *irdp = &zi->irdp; struct irdp_interface *irdp = zi->irdp;
struct listnode *node; struct listnode *node;
struct connected *ifc; struct connected *ifc;
u_int32_t timer, seed; u_int32_t timer, seed;
assert(irdp);
if (irdp->flags & IF_ACTIVE) { if (irdp->flags & IF_ACTIVE) {
zlog_warn("IRDP: Interface is already active %s", ifp->name); zlog_warn("IRDP: Interface is already active %s", ifp->name);
return; return;
@ -215,7 +239,7 @@ static void irdp_if_start(struct interface *ifp, int multicast,
} }
if (set_defaults) if (set_defaults)
if_set_defaults(ifp); if_set_defaults(irdp);
irdp->irdp_sent = 0; 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) static void irdp_if_stop(struct interface *ifp)
{ {
struct zebra_if *zi = ifp->info; struct zebra_if *zi = ifp->info;
struct irdp_interface *irdp = &zi->irdp; struct irdp_interface *irdp = zi->irdp;
if (irdp == NULL) { if (irdp == NULL) {
zlog_warn("Interface %s structure is NULL", ifp->name); 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) static void irdp_if_shutdown(struct interface *ifp)
{ {
struct zebra_if *zi = ifp->info; 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) { if (irdp->flags & IF_SHUTDOWN) {
zlog_warn("IRDP: Interface is already shutdown %s", ifp->name); zlog_warn("IRDP: Interface is already shutdown %s", ifp->name);
return; return;
@ -300,8 +326,7 @@ static void irdp_if_shutdown(struct interface *ifp)
static void irdp_if_no_shutdown(struct interface *ifp) static void irdp_if_no_shutdown(struct interface *ifp)
{ {
struct zebra_if *zi = ifp->info; struct irdp_interface *irdp = irdp_if_get(ifp);
struct irdp_interface *irdp = &zi->irdp;
if (!(irdp->flags & IF_SHUTDOWN)) { if (!(irdp->flags & IF_SHUTDOWN)) {
zlog_warn("IRDP: Interface is not shutdown %s", ifp->name); 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) int irdp_config_write(struct vty *vty, struct interface *ifp)
{ {
struct zebra_if *zi = ifp->info; struct zebra_if *zi = ifp->info;
struct irdp_interface *irdp = &zi->irdp; struct irdp_interface *irdp = zi->irdp;
struct Adv *adv; struct Adv *adv;
struct listnode *node; struct listnode *node;
char b1[INET_ADDRSTRLEN]; char b1[INET_ADDRSTRLEN];
if (!irdp)
return 0;
if (irdp->flags & IF_ACTIVE || irdp->flags & IF_SHUTDOWN) { if (irdp->flags & IF_ACTIVE || irdp->flags & IF_SHUTDOWN) {
if (irdp->flags & IF_SHUTDOWN) if (irdp->flags & IF_SHUTDOWN)
@ -360,6 +388,7 @@ DEFUN (ip_irdp_multicast,
"Use multicast mode\n") "Use multicast mode\n")
{ {
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
irdp_if_get(ifp);
irdp_if_start(ifp, TRUE, TRUE); irdp_if_start(ifp, TRUE, TRUE);
return CMD_SUCCESS; return CMD_SUCCESS;
@ -373,6 +402,7 @@ DEFUN (ip_irdp_broadcast,
"Use broadcast mode\n") "Use broadcast mode\n")
{ {
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
irdp_if_get(ifp);
irdp_if_start(ifp, FALSE, TRUE); irdp_if_start(ifp, FALSE, TRUE);
return CMD_SUCCESS; return CMD_SUCCESS;
@ -428,11 +458,7 @@ DEFUN (ip_irdp_holdtime,
{ {
int idx_number = 3; int idx_number = 3;
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
struct zebra_if *zi; struct irdp_interface *irdp = irdp_if_get(ifp);
struct irdp_interface *irdp;
zi = ifp->info;
irdp = &zi->irdp;
irdp->Lifetime = atoi(argv[idx_number]->arg); irdp->Lifetime = atoi(argv[idx_number]->arg);
return CMD_SUCCESS; return CMD_SUCCESS;
@ -448,11 +474,7 @@ DEFUN (ip_irdp_minadvertinterval,
{ {
int idx_number = 3; int idx_number = 3;
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
struct zebra_if *zi; struct irdp_interface *irdp = irdp_if_get(ifp);
struct irdp_interface *irdp;
zi = ifp->info;
irdp = &zi->irdp;
if ((unsigned)atoi(argv[idx_number]->arg) <= irdp->MaxAdvertInterval) { if ((unsigned)atoi(argv[idx_number]->arg) <= irdp->MaxAdvertInterval) {
irdp->MinAdvertInterval = atoi(argv[idx_number]->arg); irdp->MinAdvertInterval = atoi(argv[idx_number]->arg);
@ -475,11 +497,7 @@ DEFUN (ip_irdp_maxadvertinterval,
{ {
int idx_number = 3; int idx_number = 3;
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
struct zebra_if *zi; struct irdp_interface *irdp = irdp_if_get(ifp);
struct irdp_interface *irdp;
zi = ifp->info;
irdp = &zi->irdp;
if (irdp->MinAdvertInterval <= (unsigned)atoi(argv[idx_number]->arg)) { if (irdp->MinAdvertInterval <= (unsigned)atoi(argv[idx_number]->arg)) {
irdp->MaxAdvertInterval = atoi(argv[idx_number]->arg); irdp->MaxAdvertInterval = atoi(argv[idx_number]->arg);
@ -507,11 +525,7 @@ DEFUN (ip_irdp_preference,
{ {
int idx_number = 3; int idx_number = 3;
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
struct zebra_if *zi; struct irdp_interface *irdp = irdp_if_get(ifp);
struct irdp_interface *irdp;
zi = ifp->info;
irdp = &zi->irdp;
irdp->Preference = atoi(argv[idx_number]->arg); irdp->Preference = atoi(argv[idx_number]->arg);
return CMD_SUCCESS; return CMD_SUCCESS;
@ -530,17 +544,13 @@ DEFUN (ip_irdp_address_preference,
int idx_ipv4 = 3; int idx_ipv4 = 3;
int idx_number = 5; int idx_number = 5;
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
struct irdp_interface *irdp = irdp_if_get(ifp);
struct listnode *node; struct listnode *node;
struct in_addr ip; struct in_addr ip;
int pref; int pref;
int ret; int ret;
struct zebra_if *zi;
struct irdp_interface *irdp;
struct Adv *adv; struct Adv *adv;
zi = ifp->info;
irdp = &zi->irdp;
ret = inet_aton(argv[idx_ipv4]->arg, &ip); ret = inet_aton(argv[idx_ipv4]->arg, &ip);
if (!ret) if (!ret)
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
@ -572,16 +582,12 @@ DEFUN (no_ip_irdp_address_preference,
{ {
int idx_ipv4 = 4; int idx_ipv4 = 4;
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
struct irdp_interface *irdp = irdp_if_get(ifp);
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct in_addr ip; struct in_addr ip;
int ret; int ret;
struct zebra_if *zi;
struct irdp_interface *irdp;
struct Adv *adv; struct Adv *adv;
zi = ifp->info;
irdp = &zi->irdp;
ret = inet_aton(argv[idx_ipv4]->arg, &ip); ret = inet_aton(argv[idx_ipv4]->arg, &ip);
if (!ret) if (!ret)
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
@ -605,11 +611,7 @@ DEFUN (ip_irdp_debug_messages,
"Enable debugging for IRDP messages\n") "Enable debugging for IRDP messages\n")
{ {
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
struct zebra_if *zi; struct irdp_interface *irdp = irdp_if_get(ifp);
struct irdp_interface *irdp;
zi = ifp->info;
irdp = &zi->irdp;
irdp->flags |= IF_DEBUG_MESSAGES; irdp->flags |= IF_DEBUG_MESSAGES;
@ -625,11 +627,7 @@ DEFUN (ip_irdp_debug_misc,
"Enable debugging for miscellaneous IRDP events\n") "Enable debugging for miscellaneous IRDP events\n")
{ {
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
struct zebra_if *zi; struct irdp_interface *irdp = irdp_if_get(ifp);
struct irdp_interface *irdp;
zi = ifp->info;
irdp = &zi->irdp;
irdp->flags |= IF_DEBUG_MISC; irdp->flags |= IF_DEBUG_MISC;
@ -645,11 +643,7 @@ DEFUN (ip_irdp_debug_packet,
"Enable debugging for IRDP packets\n") "Enable debugging for IRDP packets\n")
{ {
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
struct zebra_if *zi; struct irdp_interface *irdp = irdp_if_get(ifp);
struct irdp_interface *irdp;
zi = ifp->info;
irdp = &zi->irdp;
irdp->flags |= IF_DEBUG_PACKET; irdp->flags |= IF_DEBUG_PACKET;
@ -666,11 +660,7 @@ DEFUN (ip_irdp_debug_disable,
"Disable debugging for all IRDP events\n") "Disable debugging for all IRDP events\n")
{ {
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
struct zebra_if *zi; struct irdp_interface *irdp = irdp_if_get(ifp);
struct irdp_interface *irdp;
zi = ifp->info;
irdp = &zi->irdp;
irdp->flags &= ~IF_DEBUG_PACKET; irdp->flags &= ~IF_DEBUG_PACKET;
irdp->flags &= ~IF_DEBUG_MESSAGES; irdp->flags &= ~IF_DEBUG_MESSAGES;
@ -682,6 +672,7 @@ DEFUN (ip_irdp_debug_disable,
void irdp_if_init() void irdp_if_init()
{ {
hook_register(zebra_if_config_wr, irdp_config_write); 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_broadcast_cmd);
install_element(INTERFACE_NODE, &ip_irdp_multicast_cmd); install_element(INTERFACE_NODE, &ip_irdp_multicast_cmd);

View File

@ -52,6 +52,7 @@
#include "zclient.h" #include "zclient.h"
#include "thread.h" #include "thread.h"
#include "privs.h" #include "privs.h"
#include "libfrr.h"
#include "zebra/interface.h" #include "zebra/interface.h"
#include "zebra/rtadv.h" #include "zebra/rtadv.h"
#include "zebra/rib.h" #include "zebra/rib.h"
@ -143,7 +144,7 @@ static int make_advertisement_packet(struct interface *ifp, struct prefix *p,
struct stream *s) struct stream *s)
{ {
struct zebra_if *zi = ifp->info; struct zebra_if *zi = ifp->info;
struct irdp_interface *irdp = &zi->irdp; struct irdp_interface *irdp = zi->irdp;
int size; int size;
int pref; int pref;
u_int16_t checksum; 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) static void irdp_send(struct interface *ifp, struct prefix *p, struct stream *s)
{ {
struct zebra_if *zi = ifp->info; struct zebra_if *zi = ifp->info;
struct irdp_interface *irdp = &zi->irdp; struct irdp_interface *irdp = zi->irdp;
char buf[PREFIX_STRLEN]; char buf[PREFIX_STRLEN];
u_int32_t dst; u_int32_t dst;
u_int32_t ttl = 1; u_int32_t ttl = 1;
if (!irdp)
return;
if (!(ifp->flags & IFF_UP)) if (!(ifp->flags & IFF_UP))
return; return;
@ -211,11 +214,14 @@ int irdp_send_thread(struct thread *t_advert)
u_int32_t timer, tmp; u_int32_t timer, tmp;
struct interface *ifp = THREAD_ARG(t_advert); struct interface *ifp = THREAD_ARG(t_advert);
struct zebra_if *zi = ifp->info; struct zebra_if *zi = ifp->info;
struct irdp_interface *irdp = &zi->irdp; struct irdp_interface *irdp = zi->irdp;
struct prefix *p; struct prefix *p;
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct connected *ifc; struct connected *ifc;
if (!irdp)
return 0;
irdp->flags &= ~IF_SOLICIT; irdp->flags &= ~IF_SOLICIT;
if (ifp->connected) if (ifp->connected)
@ -250,12 +256,15 @@ int irdp_send_thread(struct thread *t_advert)
void irdp_advert_off(struct interface *ifp) void irdp_advert_off(struct interface *ifp)
{ {
struct zebra_if *zi = ifp->info; struct zebra_if *zi = ifp->info;
struct irdp_interface *irdp = &zi->irdp; struct irdp_interface *irdp = zi->irdp;
struct listnode *node, *nnode; struct listnode *node, *nnode;
int i; int i;
struct connected *ifc; struct connected *ifc;
struct prefix *p; struct prefix *p;
if (!irdp)
return;
if (irdp->t_advertise) if (irdp->t_advertise)
thread_cancel(irdp->t_advertise); thread_cancel(irdp->t_advertise);
irdp->t_advertise = NULL; irdp->t_advertise = NULL;
@ -279,9 +288,12 @@ void irdp_advert_off(struct interface *ifp)
void process_solicit(struct interface *ifp) void process_solicit(struct interface *ifp)
{ {
struct zebra_if *zi = ifp->info; struct zebra_if *zi = ifp->info;
struct irdp_interface *irdp = &zi->irdp; struct irdp_interface *irdp = zi->irdp;
u_int32_t timer; u_int32_t timer;
if (!irdp)
return;
/* When SOLICIT is active we reject further incoming solicits /* When SOLICIT is active we reject further incoming solicits
this keeps down the answering rate so we don't have think this keeps down the answering rate so we don't have think
about DoS attacks here. */ about DoS attacks here. */
@ -317,7 +329,7 @@ static int irdp_finish(void)
if (!zi) if (!zi)
continue; continue;
irdp = &zi->irdp; irdp = zi->irdp;
if (!irdp) if (!irdp)
continue; continue;
@ -326,6 +338,7 @@ static int irdp_finish(void)
irdp_advert_off(ifp); irdp_advert_off(ifp);
} }
} }
return 0;
} }
void irdp_init(void) void irdp_init(void)

View File

@ -84,7 +84,7 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp)
if (!zi) if (!zi)
return; return;
irdp = &zi->irdp; irdp = zi->irdp;
if (!irdp) if (!irdp)
return; return;
@ -240,7 +240,7 @@ int irdp_read_raw(struct thread *r)
if (!zi) if (!zi)
return ret; return ret;
irdp = &zi->irdp; irdp = zi->irdp;
if (!irdp) if (!irdp)
return ret; return ret;