From 11928ecf19e8b750b731b526863668197f38f9d6 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 14 Jan 2022 18:03:21 +0100 Subject: [PATCH] pim6d: IPv6-adjust Hello/TLV processing Signed-off-by: David Lamparter --- pimd/pim_hello.c | 168 ++++++++++++++++------------------------------- pimd/pim_hello.h | 4 +- pimd/pim_tlv.c | 113 +++++++++++++------------------ pimd/pim_tlv.h | 10 +-- 4 files changed, 109 insertions(+), 186 deletions(-) diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c index 45ea6a9562..fe4f10aa6a 100644 --- a/pimd/pim_hello.c +++ b/pimd/pim_hello.c @@ -33,81 +33,62 @@ #include "pim_upstream.h" #include "pim_bsm.h" -static void on_trace(const char *label, struct interface *ifp, - struct in_addr src) +static void on_trace(const char *label, struct interface *ifp, pim_addr src) { - if (PIM_DEBUG_PIM_TRACE) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src, src_str, sizeof(src_str)); - zlog_debug("%s: from %s on %s", label, src_str, ifp->name); - } + if (PIM_DEBUG_PIM_TRACE) + zlog_debug("%s: from %pPAs on %s", label, &src, ifp->name); } static void tlv_trace_bool(const char *label, const char *tlv_name, - const char *ifname, struct in_addr src_addr, - int isset, int value) + const char *ifname, pim_addr src_addr, int isset, + int value) { - if (isset) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, sizeof(src_str)); + if (isset) zlog_debug( - "%s: PIM hello option from %s on interface %s: %s=%d", - label, src_str, ifname, tlv_name, value); - } + "%s: PIM hello option from %pPAs on interface %s: %s=%d", + label, &src_addr, ifname, tlv_name, value); } static void tlv_trace_uint16(const char *label, const char *tlv_name, - const char *ifname, struct in_addr src_addr, - int isset, uint16_t value) + const char *ifname, pim_addr src_addr, int isset, + uint16_t value) { - if (isset) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, sizeof(src_str)); + if (isset) zlog_debug( - "%s: PIM hello option from %s on interface %s: %s=%u", - label, src_str, ifname, tlv_name, value); - } + "%s: PIM hello option from %pPAs on interface %s: %s=%u", + label, &src_addr, ifname, tlv_name, value); } static void tlv_trace_uint32(const char *label, const char *tlv_name, - const char *ifname, struct in_addr src_addr, - int isset, uint32_t value) + const char *ifname, pim_addr src_addr, int isset, + uint32_t value) { - if (isset) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, sizeof(src_str)); + if (isset) zlog_debug( - "%s: PIM hello option from %s on interface %s: %s=%u", - label, src_str, ifname, tlv_name, value); - } + "%s: PIM hello option from %pPAs on interface %s: %s=%u", + label, &src_addr, ifname, tlv_name, value); } static void tlv_trace_uint32_hex(const char *label, const char *tlv_name, - const char *ifname, struct in_addr src_addr, + const char *ifname, pim_addr src_addr, int isset, uint32_t value) { - if (isset) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, sizeof(src_str)); + if (isset) zlog_debug( - "%s: PIM hello option from %s on interface %s: %s=%08x", - label, src_str, ifname, tlv_name, value); - } + "%s: PIM hello option from %pPAs on interface %s: %s=%08x", + label, &src_addr, ifname, tlv_name, value); } static void tlv_trace_list(const char *label, const char *tlv_name, - const char *ifname, struct in_addr src_addr, - int isset, struct list *addr_list) + const char *ifname, pim_addr src_addr, int isset, + struct list *addr_list) { - if (isset) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, sizeof(src_str)); + if (isset) zlog_debug( - "%s: PIM hello option from %s on interface %s: %s size=%d list=%p", - label, src_str, ifname, tlv_name, + "%s: PIM hello option from %pPAs on interface %s: %s size=%d list=%p", + label, &src_addr, ifname, tlv_name, addr_list ? ((int)listcount(addr_list)) : -1, (void *)addr_list); - } } #define FREE_ADDR_LIST \ @@ -121,8 +102,8 @@ static void tlv_trace_list(const char *label, const char *tlv_name, return (code); \ } -int pim_hello_recv(struct interface *ifp, struct in_addr src_addr, - uint8_t *tlv_buf, int tlv_buf_size) +int pim_hello_recv(struct interface *ifp, pim_addr src_addr, uint8_t *tlv_buf, + int tlv_buf_size) { struct pim_interface *pim_ifp; struct pim_neighbor *neigh; @@ -158,15 +139,11 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr, int remain = tlv_pastend - tlv_curr; if (remain < PIM_TLV_MIN_SIZE) { - if (PIM_DEBUG_PIM_HELLO) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, - sizeof(src_str)); + if (PIM_DEBUG_PIM_HELLO) zlog_debug( - "%s: short PIM hello TLV size=%d < min=%d from %s on interface %s", + "%s: short PIM hello TLV size=%d < min=%d from %pPAs on interface %s", __func__, remain, PIM_TLV_MIN_SIZE, - src_str, ifp->name); - } + &src_addr, ifp->name); FREE_ADDR_LIST_THEN_RETURN(-1); } @@ -176,28 +153,20 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr, tlv_curr += PIM_TLV_LENGTH_SIZE; if ((tlv_curr + option_len) > tlv_pastend) { - if (PIM_DEBUG_PIM_HELLO) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, - sizeof(src_str)); + if (PIM_DEBUG_PIM_HELLO) zlog_debug( - "%s: long PIM hello TLV type=%d length=%d > left=%td from %s on interface %s", + "%s: long PIM hello TLV type=%d length=%d > left=%td from %pPAs on interface %s", __func__, option_type, option_len, - tlv_pastend - tlv_curr, src_str, + tlv_pastend - tlv_curr, &src_addr, ifp->name); - } FREE_ADDR_LIST_THEN_RETURN(-2); } - if (PIM_DEBUG_PIM_HELLO) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, - sizeof(src_str)); + if (PIM_DEBUG_PIM_HELLO) zlog_debug( - "%s: parse left_size=%d: PIM hello TLV type=%d length=%d from %s on %s", + "%s: parse left_size=%d: PIM hello TLV type=%d length=%d from %pPAs on %s", __func__, remain, option_type, option_len, - src_str, ifp->name); - } + &src_addr, ifp->name); switch (option_type) { case PIM_MSG_OPTION_TYPE_HOLDTIME: @@ -242,26 +211,18 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr, } break; case PIM_MSG_OPTION_TYPE_DM_STATE_REFRESH: - if (PIM_DEBUG_PIM_HELLO) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, - sizeof(src_str)); + if (PIM_DEBUG_PIM_HELLO) zlog_debug( - "%s: ignoring PIM hello dense-mode state refresh TLV option type=%d length=%d from %s on interface %s", + "%s: ignoring PIM hello dense-mode state refresh TLV option type=%d length=%d from %pPAs on interface %s", __func__, option_type, option_len, - src_str, ifp->name); - } + &src_addr, ifp->name); break; default: - if (PIM_DEBUG_PIM_HELLO) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, - sizeof(src_str)); + if (PIM_DEBUG_PIM_HELLO) zlog_debug( - "%s: ignoring unknown PIM hello TLV type=%d length=%d from %s on interface %s", + "%s: ignoring unknown PIM hello TLV type=%d length=%d from %pPAs on interface %s", __func__, option_type, option_len, - src_str, ifp->name); - } + &src_addr, ifp->name); } tlv_curr += option_len; @@ -310,14 +271,10 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr, } if (!PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_HOLDTIME)) { - if (PIM_DEBUG_PIM_HELLO) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, - sizeof(src_str)); + if (PIM_DEBUG_PIM_HELLO) zlog_debug( - "%s: PIM hello missing holdtime from %s on interface %s", - __func__, src_str, ifp->name); - } + "%s: PIM hello missing holdtime from %pPAs on interface %s", + __func__, &src_addr, ifp->name); } /* @@ -335,14 +292,10 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr, hello_option_dr_priority, hello_option_generation_id, hello_option_addr_list, PIM_NEIGHBOR_SEND_DELAY); if (!neigh) { - if (PIM_DEBUG_PIM_HELLO) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, - sizeof(src_str)); + if (PIM_DEBUG_PIM_HELLO) zlog_warn( - "%s: failure creating PIM neighbor %s on interface %s", - __func__, src_str, ifp->name); - } + "%s: failure creating PIM neighbor %pPAs on interface %s", + __func__, &src_addr, ifp->name); FREE_ADDR_LIST_THEN_RETURN(-8); } /* Forward BSM if required */ @@ -368,16 +321,12 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr, || (hello_option_generation_id != neigh->generation_id)) { /* GenID mismatch, then replace neighbor */ - if (PIM_DEBUG_PIM_HELLO) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, - sizeof(src_str)); + if (PIM_DEBUG_PIM_HELLO) zlog_debug( - "%s: GenId mismatch new=%08x old=%08x: replacing neighbor %s on %s", + "%s: GenId mismatch new=%08x old=%08x: replacing neighbor %pPAs on %s", __func__, hello_option_generation_id, - neigh->generation_id, src_str, + neigh->generation_id, &src_addr, ifp->name); - } pim_upstream_rpf_genid_changed(pim_ifp->pim, neigh->source_addr); @@ -392,15 +341,10 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr, hello_option_addr_list, PIM_NEIGHBOR_SEND_NOW); if (!neigh) { - if (PIM_DEBUG_PIM_HELLO) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, - src_str, - sizeof(src_str)); + if (PIM_DEBUG_PIM_HELLO) zlog_debug( - "%s: failure re-creating PIM neighbor %s on interface %s", - __func__, src_str, ifp->name); - } + "%s: failure re-creating PIM neighbor %pPAs on interface %s", + __func__, &src_addr, ifp->name); FREE_ADDR_LIST_THEN_RETURN(-9); } /* Forward BSM if required */ diff --git a/pimd/pim_hello.h b/pimd/pim_hello.h index df41f97d9e..56084e06d2 100644 --- a/pimd/pim_hello.h +++ b/pimd/pim_hello.h @@ -24,8 +24,8 @@ #include "if.h" -int pim_hello_recv(struct interface *ifp, struct in_addr src_addr, - uint8_t *tlv_buf, int tlv_buf_size); +int pim_hello_recv(struct interface *ifp, pim_addr src_addr, uint8_t *tlv_buf, + int tlv_buf_size); int pim_hello_build_tlv(struct interface *ifp, uint8_t *tlv_buf, int tlv_buf_size, uint16_t holdtime, diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c index f38eed8cb1..86403dd54a 100644 --- a/pimd/pim_tlv.c +++ b/pimd/pim_tlv.c @@ -290,15 +290,13 @@ uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend, } static int check_tlv_length(const char *label, const char *tlv_name, - const char *ifname, struct in_addr src_addr, + const char *ifname, pim_addr src_addr, int correct_len, int option_len) { if (option_len != correct_len) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, sizeof(src_str)); zlog_warn( - "%s: PIM hello %s TLV with incorrect value size=%d correct=%d from %s on interface %s", - label, tlv_name, option_len, correct_len, src_str, + "%s: PIM hello %s TLV with incorrect value size=%d correct=%d from %pPAs on interface %s", + label, tlv_name, option_len, correct_len, &src_addr, ifname); return -1; } @@ -306,49 +304,44 @@ static int check_tlv_length(const char *label, const char *tlv_name, return 0; } -static void check_tlv_redefinition_uint16( - const char *label, const char *tlv_name, const char *ifname, - struct in_addr src_addr, pim_hello_options options, - pim_hello_options opt_mask, uint16_t new, uint16_t old) +static void check_tlv_redefinition_uint16(const char *label, + const char *tlv_name, + const char *ifname, pim_addr src_addr, + pim_hello_options options, + pim_hello_options opt_mask, + uint16_t new, uint16_t old) { - if (PIM_OPTION_IS_SET(options, opt_mask)) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, sizeof(src_str)); + if (PIM_OPTION_IS_SET(options, opt_mask)) zlog_warn( - "%s: PIM hello TLV redefined %s=%u old=%u from %s on interface %s", - label, tlv_name, new, old, src_str, ifname); - } + "%s: PIM hello TLV redefined %s=%u old=%u from %pPAs on interface %s", + label, tlv_name, new, old, &src_addr, ifname); } -static void check_tlv_redefinition_uint32( - const char *label, const char *tlv_name, const char *ifname, - struct in_addr src_addr, pim_hello_options options, - pim_hello_options opt_mask, uint32_t new, uint32_t old) +static void check_tlv_redefinition_uint32(const char *label, + const char *tlv_name, + const char *ifname, pim_addr src_addr, + pim_hello_options options, + pim_hello_options opt_mask, + uint32_t new, uint32_t old) { - if (PIM_OPTION_IS_SET(options, opt_mask)) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, sizeof(src_str)); + if (PIM_OPTION_IS_SET(options, opt_mask)) zlog_warn( - "%s: PIM hello TLV redefined %s=%u old=%u from %s on interface %s", - label, tlv_name, new, old, src_str, ifname); - } + "%s: PIM hello TLV redefined %s=%u old=%u from %pPAs on interface %s", + label, tlv_name, new, old, &src_addr, ifname); } static void check_tlv_redefinition_uint32_hex( const char *label, const char *tlv_name, const char *ifname, - struct in_addr src_addr, pim_hello_options options, + pim_addr src_addr, pim_hello_options options, pim_hello_options opt_mask, uint32_t new, uint32_t old) { - if (PIM_OPTION_IS_SET(options, opt_mask)) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, sizeof(src_str)); + if (PIM_OPTION_IS_SET(options, opt_mask)) zlog_warn( - "%s: PIM hello TLV redefined %s=%08x old=%08x from %s on interface %s", - label, tlv_name, new, old, src_str, ifname); - } + "%s: PIM hello TLV redefined %s=%08x old=%08x from %pPAs on interface %s", + label, tlv_name, new, old, &src_addr, ifname); } -int pim_tlv_parse_holdtime(const char *ifname, struct in_addr src_addr, +int pim_tlv_parse_holdtime(const char *ifname, pim_addr src_addr, pim_hello_options *hello_options, uint16_t *hello_option_holdtime, uint16_t option_len, const uint8_t *tlv_curr) @@ -372,7 +365,7 @@ int pim_tlv_parse_holdtime(const char *ifname, struct in_addr src_addr, return 0; } -int pim_tlv_parse_lan_prune_delay(const char *ifname, struct in_addr src_addr, +int pim_tlv_parse_lan_prune_delay(const char *ifname, pim_addr src_addr, pim_hello_options *hello_options, uint16_t *hello_option_propagation_delay, uint16_t *hello_option_override_interval, @@ -408,7 +401,7 @@ int pim_tlv_parse_lan_prune_delay(const char *ifname, struct in_addr src_addr, return 0; } -int pim_tlv_parse_dr_priority(const char *ifname, struct in_addr src_addr, +int pim_tlv_parse_dr_priority(const char *ifname, pim_addr src_addr, pim_hello_options *hello_options, uint32_t *hello_option_dr_priority, uint16_t option_len, const uint8_t *tlv_curr) @@ -432,7 +425,7 @@ int pim_tlv_parse_dr_priority(const char *ifname, struct in_addr src_addr, return 0; } -int pim_tlv_parse_generation_id(const char *ifname, struct in_addr src_addr, +int pim_tlv_parse_generation_id(const char *ifname, pim_addr src_addr, pim_hello_options *hello_options, uint32_t *hello_option_generation_id, uint16_t option_len, const uint8_t *tlv_curr) @@ -682,7 +675,7 @@ int pim_parse_addr_source(pim_sgaddr *sg, uint8_t *flags, const uint8_t *buf, } \ } -int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr, +int pim_tlv_parse_addr_list(const char *ifname, pim_addr src_addr, pim_hello_options *hello_options, struct list **hello_option_addr_list, uint16_t option_len, const uint8_t *tlv_curr) @@ -698,7 +691,7 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr, addr = tlv_curr; pastend = tlv_curr + option_len; while (addr < pastend) { - struct prefix tmp; + struct prefix tmp, src_pfx; int addr_offset; /* @@ -707,12 +700,9 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr, addr_offset = pim_parse_addr_ucast_prefix(&tmp, addr, pastend - addr); if (addr_offset < 1) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, - sizeof(src_str)); zlog_warn( - "%s: pim_parse_addr_ucast() failure: from %s on %s", - __func__, src_str, ifname); + "%s: pim_parse_addr_ucast() failure: from %pPAs on %s", + __func__, &src_addr, ifname); FREE_ADDR_LIST(*hello_option_addr_list); return -1; } @@ -725,35 +715,28 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr, switch (tmp.family) { case AF_INET: { char addr_str[INET_ADDRSTRLEN]; - char src_str[INET_ADDRSTRLEN]; pim_inet4_dump("", tmp.u.prefix4, addr_str, sizeof(addr_str)); - pim_inet4_dump("", src_addr, src_str, - sizeof(src_str)); zlog_debug( - "%s: PIM hello TLV option: list_old_size=%d IPv4 address %s from %s on %s", + "%s: PIM hello TLV option: list_old_size=%d IPv4 address %s from %pPAs on %s", __func__, *hello_option_addr_list ? ((int)listcount( - *hello_option_addr_list)) + *hello_option_addr_list)) : -1, - addr_str, src_str, ifname); + addr_str, &src_addr, ifname); } break; case AF_INET6: break; - default: { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, - sizeof(src_str)); + default: zlog_debug( - "%s: PIM hello TLV option: list_old_size=%d UNKNOWN address family from %s on %s", + "%s: PIM hello TLV option: list_old_size=%d UNKNOWN address family from %pPAs on %s", __func__, *hello_option_addr_list ? ((int)listcount( - *hello_option_addr_list)) + *hello_option_addr_list)) : -1, - src_str, ifname); - } + &src_addr, ifname); } } @@ -761,16 +744,12 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr, Exclude neighbor's primary address if incorrectly included in the secondary address list */ - if (tmp.family == AF_INET) { - if (tmp.u.prefix4.s_addr == src_addr.s_addr) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", src_addr, src_str, - sizeof(src_str)); - zlog_warn( - "%s: ignoring primary address in secondary list from %s on %s", - __func__, src_str, ifname); - continue; - } + pim_addr_to_prefix(&src_pfx, src_addr); + if (!prefix_cmp(&tmp, &src_pfx)) { + zlog_warn( + "%s: ignoring primary address in secondary list from %pPAs on %s", + __func__, &src_addr, ifname); + continue; } /* diff --git a/pimd/pim_tlv.h b/pimd/pim_tlv.h index 614c30a488..64b3a0b6ba 100644 --- a/pimd/pim_tlv.h +++ b/pimd/pim_tlv.h @@ -84,24 +84,24 @@ uint8_t *pim_tlv_append_uint32(uint8_t *buf, const uint8_t *buf_pastend, uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend, struct list *ifconnected, int family); -int pim_tlv_parse_holdtime(const char *ifname, struct in_addr src_addr, +int pim_tlv_parse_holdtime(const char *ifname, pim_addr src_addr, pim_hello_options *hello_options, uint16_t *hello_option_holdtime, uint16_t option_len, const uint8_t *tlv_curr); -int pim_tlv_parse_lan_prune_delay(const char *ifname, struct in_addr src_addr, +int pim_tlv_parse_lan_prune_delay(const char *ifname, pim_addr src_addr, pim_hello_options *hello_options, uint16_t *hello_option_propagation_delay, uint16_t *hello_option_override_interval, uint16_t option_len, const uint8_t *tlv_curr); -int pim_tlv_parse_dr_priority(const char *ifname, struct in_addr src_addr, +int pim_tlv_parse_dr_priority(const char *ifname, pim_addr src_addr, pim_hello_options *hello_options, uint32_t *hello_option_dr_priority, uint16_t option_len, const uint8_t *tlv_curr); -int pim_tlv_parse_generation_id(const char *ifname, struct in_addr src_addr, +int pim_tlv_parse_generation_id(const char *ifname, pim_addr src_addr, pim_hello_options *hello_options, uint32_t *hello_option_generation_id, uint16_t option_len, const uint8_t *tlv_curr); -int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr, +int pim_tlv_parse_addr_list(const char *ifname, pim_addr src_addr, pim_hello_options *hello_options, struct list **hello_option_addr_list, uint16_t option_len, const uint8_t *tlv_curr); -- 2.39.5