diff options
| author | David Lamparter <equinox@opensourcerouting.org> | 2022-01-14 16:38:41 +0100 | 
|---|---|---|
| committer | David Lamparter <equinox@opensourcerouting.org> | 2022-02-14 06:45:03 +0100 | 
| commit | 0d360092045fdfca1a363bbc522deafbb79255e8 (patch) | |
| tree | 9ce974e3fb9af2dfb2b6ea5e35c92328dbd115a0 | |
| parent | 16763d77a39ae0cd84e6fcf4b3f6a05f10d94c38 (diff) | |
pim6d: more TLV parse/encode IPv6 preparation
More proliferation of pim_addr to work towards IPV6.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
| -rw-r--r-- | pimd/pim_assert.c | 21 | ||||
| -rw-r--r-- | pimd/pim_join.c | 39 | ||||
| -rw-r--r-- | pimd/pim_register.c | 16 | ||||
| -rw-r--r-- | pimd/pim_tlv.c | 115 | ||||
| -rw-r--r-- | pimd/pim_tlv.h | 10 | 
5 files changed, 113 insertions, 88 deletions
diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c index 3c38ebd76b..f4b6e81bd6 100644 --- a/pimd/pim_assert.c +++ b/pimd/pim_assert.c @@ -216,7 +216,8 @@ int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,  		    struct in_addr src_addr, uint8_t *buf, int buf_size)  {  	pim_sgaddr sg; -	struct prefix msg_source_addr; +	pim_addr msg_source_addr; +	bool wrong_af = false;  	struct pim_assert_metric msg_metric;  	int offset;  	uint8_t *curr; @@ -246,8 +247,9 @@ int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,  	/*  	  Parse assert source addr  	*/ -	offset = pim_parse_addr_ucast(&msg_source_addr, curr, curr_size); -	if (offset < 1) { +	offset = pim_parse_addr_ucast(&msg_source_addr, curr, curr_size, +				      &wrong_af); +	if (offset < 1 || wrong_af) {  		char src_str[INET_ADDRSTRLEN];  		pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));  		zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s", @@ -286,15 +288,13 @@ int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,  	if (PIM_DEBUG_PIM_TRACE) {  		char neigh_str[INET_ADDRSTRLEN]; -		char source_str[INET_ADDRSTRLEN];  		pim_inet4_dump("<neigh?>", src_addr, neigh_str,  			       sizeof(neigh_str)); -		pim_inet4_dump("<src?>", msg_source_addr.u.prefix4, source_str, -			       sizeof(source_str));  		zlog_debug( -			"%s: from %s on %s: (S,G)=(%s,%pPAs) pref=%u metric=%u rpt_bit=%u", -			__func__, neigh_str, ifp->name, source_str, &sg.grp, -			msg_metric.metric_preference, msg_metric.route_metric, +			"%s: from %s on %s: (S,G)=(%pPAs,%pPAs) pref=%u metric=%u rpt_bit=%u", +			__func__, neigh_str, ifp->name, &msg_source_addr, +			&sg.grp, msg_metric.metric_preference, +			msg_metric.route_metric,  			PIM_FORCE_BOOLEAN(msg_metric.rpt_bit_flag));  	} @@ -304,8 +304,7 @@ int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,  	assert(pim_ifp);  	++pim_ifp->pim_ifstat_assert_recv; -	return dispatch_assert(ifp, msg_source_addr.u.prefix4, sg.grp, -			       msg_metric); +	return dispatch_assert(ifp, msg_source_addr, sg.grp, msg_metric);  }  /* diff --git a/pimd/pim_join.c b/pimd/pim_join.c index 22890dc372..a3a97f20e5 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -165,7 +165,8 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,  		       struct in_addr src_addr, uint8_t *tlv_buf,  		       int tlv_buf_size)  { -	struct prefix msg_upstream_addr; +	pim_addr msg_upstream_addr; +	bool wrong_af = false;  	struct pim_interface *pim_ifp;  	uint8_t msg_num_groups;  	uint16_t msg_holdtime; @@ -184,8 +185,8 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,  	/*  	  Parse ucast addr  	*/ -	addr_offset = -		pim_parse_addr_ucast(&msg_upstream_addr, buf, pastend - buf); +	addr_offset = pim_parse_addr_ucast(&msg_upstream_addr, buf, +					   pastend - buf, &wrong_af);  	if (addr_offset < 1) {  		char src_str[INET_ADDRSTRLEN];  		pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str)); @@ -198,12 +199,12 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,  	/*  	  Check upstream address family  	 */ -	if (msg_upstream_addr.family != AF_INET) { +	if (wrong_af) {  		char src_str[INET_ADDRSTRLEN];  		pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));  		zlog_warn( -			"%s: ignoring join/prune directed to unexpected addr family=%d from %s on %s", -			__func__, msg_upstream_addr.family, src_str, ifp->name); +			"%s: ignoring join/prune directed to unexpected addr family from %s on %s", +			__func__, src_str, ifp->name);  		return -2;  	} @@ -226,14 +227,11 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,  	if (PIM_DEBUG_PIM_J_P) {  		char src_str[INET_ADDRSTRLEN]; -		char upstream_str[INET_ADDRSTRLEN];  		pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str)); -		pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4, -			       upstream_str, sizeof(upstream_str));  		zlog_debug( -			"%s: join/prune upstream=%s groups=%d holdtime=%d from %s on %s", -			__func__, upstream_str, msg_num_groups, msg_holdtime, -			src_str, ifp->name); +			"%s: join/prune upstream=%pPAs groups=%d holdtime=%d from %s on %s", +			__func__, &msg_upstream_addr, msg_num_groups, +			msg_holdtime, src_str, ifp->name);  	}  	/* Scan groups */ @@ -271,14 +269,11 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,  		if (PIM_DEBUG_PIM_J_P) {  			char src_str[INET_ADDRSTRLEN]; -			char upstream_str[INET_ADDRSTRLEN];  			pim_inet4_dump("<src?>", src_addr, src_str,  				       sizeof(src_str)); -			pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4, -				       upstream_str, sizeof(upstream_str));  			zlog_debug( -				"%s: join/prune upstream=%s group=%pPA/32 join_src=%d prune_src=%d from %s on %s", -				__func__, upstream_str, &sg.grp, +				"%s: join/prune upstream=%pPAs group=%pPA/32 join_src=%d prune_src=%d from %s on %s", +				__func__, &msg_upstream_addr, &sg.grp,  				msg_num_joined_sources, msg_num_pruned_sources,  				src_str, ifp->name);  		} @@ -300,9 +295,8 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,  			if (filtered)  				continue; -			recv_join(ifp, neigh, msg_holdtime, -				  msg_upstream_addr.u.prefix4, &sg, -				  msg_source_flags); +			recv_join(ifp, neigh, msg_holdtime, msg_upstream_addr, +				  &sg, msg_source_flags);  			if (pim_addr_is_any(sg.src)) {  				starg_ch = pim_ifchannel_find(ifp, &sg); @@ -326,9 +320,8 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,  			if (filtered)  				continue; -			recv_prune(ifp, neigh, msg_holdtime, -				   msg_upstream_addr.u.prefix4, &sg, -				   msg_source_flags); +			recv_prune(ifp, neigh, msg_holdtime, msg_upstream_addr, +				   &sg, msg_source_flags);  			/*  			 * So if we are receiving a S,G,RPT prune  			 * before we have any data for that S,G diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 855d912566..a0def299fa 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -72,7 +72,6 @@ void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg,  	unsigned int b1length = 0;  	unsigned int length;  	uint8_t *b1; -	struct prefix p;  	if (PIM_DEBUG_PIM_REG) {  		zlog_debug("Sending Register stop for %pSG to %pI4 on %s", sg, @@ -86,10 +85,7 @@ void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg,  	b1length += length;  	b1 += length; -	p.family = AF_INET; -	p.u.prefix4 = sg->src; -	p.prefixlen = IPV4_MAX_BITLEN; -	length = pim_encode_addr_ucast(b1, &p); +	length = pim_encode_addr_ucast(b1, sg->src);  	b1length += length;  	pim_msg_build_header(buffer, b1length + PIM_MSG_REGISTER_STOP_LEN, @@ -117,8 +113,8 @@ int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)  	struct pim_interface *pim_ifp = ifp->info;  	struct pim_instance *pim = pim_ifp->pim;  	struct pim_upstream *upstream = NULL; -	struct prefix source;  	pim_sgaddr sg; +	bool wrong_af = false;  	int l;  	++pim_ifp->pim_ifstat_reg_stop_recv; @@ -127,8 +123,12 @@ int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)  	l = pim_parse_addr_group(&sg, buf, buf_size);  	buf += l;  	buf_size -= l; -	pim_parse_addr_ucast(&source, buf, buf_size); -	sg.src = source.u.prefix4; +	pim_parse_addr_ucast(&sg.src, buf, buf_size, &wrong_af); + +	if (wrong_af) { +		zlog_err("invalid AF in Register-Stop on %s", ifp->name); +		return 0; +	}  	upstream = pim_upstream_find(pim, &sg);  	if (!upstream) { diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c index a4f60e5198..f38eed8cb1 100644 --- a/pimd/pim_tlv.c +++ b/pimd/pim_tlv.c @@ -29,6 +29,12 @@  #include "pim_str.h"  #include "pim_msg.h" +#if PIM_IPV == 4 +#define PIM_MSG_ADDRESS_FAMILY PIM_MSG_ADDRESS_FAMILY_IPV4 +#else +#define PIM_MSG_ADDRESS_FAMILY PIM_MSG_ADDRESS_FAMILY_IPV6 +#endif +  uint8_t *pim_tlv_append_uint16(uint8_t *buf, const uint8_t *buf_pastend,  			       uint16_t option_type, uint16_t option_value)  { @@ -117,7 +123,23 @@ uint8_t *pim_tlv_append_uint32(uint8_t *buf, const uint8_t *buf_pastend,   *       The unicast address as represented by the given Address Family   *       and Encoding Type.   */ -int pim_encode_addr_ucast(uint8_t *buf, struct prefix *p) +int pim_encode_addr_ucast(uint8_t *buf, pim_addr addr) +{ +	uint8_t *start = buf; + +#if PIM_IPV == 4 +	*buf++ = PIM_MSG_ADDRESS_FAMILY_IPV4; +#else +	*buf++ = PIM_MSG_ADDRESS_FAMILY_IPV6; +#endif +	*buf++ = 0; +	memcpy(buf, &addr, sizeof(addr)); +	buf += sizeof(addr); + +	return buf - start; +} + +int pim_encode_addr_ucast_prefix(uint8_t *buf, struct prefix *p)  {  	switch (p->family) {  	case AF_INET: @@ -188,28 +210,22 @@ int pim_encode_addr_ucast(uint8_t *buf, struct prefix *p)   *       Contains the group address.   */  int pim_encode_addr_group(uint8_t *buf, afi_t afi, int bidir, int scope, -			  struct in_addr group) +			  pim_addr group)  { +	uint8_t *start = buf;  	uint8_t flags = 0;  	flags |= bidir << 8;  	flags |= scope; -	switch (afi) { -	case AFI_IP: -		*buf = PIM_MSG_ADDRESS_FAMILY_IPV4; -		++buf; -		*buf = 0; -		++buf; -		*buf = flags; -		++buf; -		*buf = 32; -		++buf; -		memcpy(buf, &group, sizeof(struct in_addr)); -		return group_ipv4_encoding_len; -	default: -		return 0; -	} +	*buf++ = PIM_MSG_ADDRESS_FAMILY; +	*buf++ = 0; +	*buf++ = flags; +	*buf++ = sizeof(group) / 8; +	memcpy(buf, &group, sizeof(group)); +	buf += sizeof(group); + +	return buf - start;  }  uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend, @@ -248,7 +264,7 @@ uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,  		if (p->family != family)  			continue; -		l_encode = pim_encode_addr_ucast(curr, p); +		l_encode = pim_encode_addr_ucast_prefix(curr, p);  		curr += l_encode;  		option_len += l_encode;  	} @@ -441,7 +457,8 @@ int pim_tlv_parse_generation_id(const char *ifname, struct in_addr src_addr,  	return 0;  } -int pim_parse_addr_ucast(struct prefix *p, const uint8_t *buf, int buf_size) +int pim_parse_addr_ucast_prefix(struct prefix *p, const uint8_t *buf, +				int buf_size)  {  	const int ucast_encoding_min_len = 3; /* 1 family + 1 type + 1 addr */  	const uint8_t *addr; @@ -510,6 +527,25 @@ int pim_parse_addr_ucast(struct prefix *p, const uint8_t *buf, int buf_size)  	return addr - buf;  } +int pim_parse_addr_ucast(pim_addr *out, const uint8_t *buf, int buf_size, +			 bool *wrong_af) +{ +	struct prefix p; +	int ret; + +	ret = pim_parse_addr_ucast_prefix(&p, buf, buf_size); +	if (ret < 0) +		return ret; + +	if (p.family != PIM_AF) { +		*wrong_af = true; +		return -5; +	} + +	memcpy(out, &p.u.val, sizeof(*out)); +	return ret; +} +  int pim_parse_addr_group(pim_sgaddr *sg, const uint8_t *buf, int buf_size)  {  	const int grp_encoding_min_len = @@ -532,40 +568,32 @@ int pim_parse_addr_group(pim_sgaddr *sg, const uint8_t *buf, int buf_size)  	family = *addr++;  	type = *addr++; -	//++addr;  	++addr; /* skip b_reserved_z fields */  	mask_len = *addr++; -	switch (family) { -	case PIM_MSG_ADDRESS_FAMILY_IPV4: -		if (type) { -			zlog_warn( -				"%s: unknown group address encoding type=%d from", -				__func__, type); -			return -2; -		} - -		if ((addr + sizeof(struct in_addr)) > pastend) { -			zlog_warn( -				"%s: IPv4 group address overflow: left=%td needed=%zu from", -				__func__, pastend - addr, -				sizeof(struct in_addr)); -			return -3; -		} - -		memcpy(&sg->grp.s_addr, addr, sizeof(struct in_addr)); - -		addr += sizeof(struct in_addr); +	if (type) { +		zlog_warn("%s: unknown group address encoding type=%d from", +			  __func__, type); +		return -2; +	} -		break; -	default: { +	if (family != PIM_MSG_ADDRESS_FAMILY) {  		zlog_warn(  			"%s: unknown group address encoding family=%d mask_len=%d from",  			__func__, family, mask_len);  		return -4;  	} + +	if ((addr + sizeof(sg->grp)) > pastend) { +		zlog_warn( +			"%s: group address overflow: left=%td needed=%zu from", +			__func__, pastend - addr, sizeof(sg->grp)); +		return -3;  	} +	memcpy(&sg->grp, addr, sizeof(sg->grp)); +	addr += sizeof(sg->grp); +  	return addr - buf;  } @@ -676,7 +704,8 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,  		/*  		  Parse ucast addr  		 */ -		addr_offset = pim_parse_addr_ucast(&tmp, addr, pastend - 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?>", src_addr, src_str, diff --git a/pimd/pim_tlv.h b/pimd/pim_tlv.h index 1aa60d5dbb..614c30a488 100644 --- a/pimd/pim_tlv.h +++ b/pimd/pim_tlv.h @@ -106,11 +106,15 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,  			    struct list **hello_option_addr_list,  			    uint16_t option_len, const uint8_t *tlv_curr); -int pim_encode_addr_ucast(uint8_t *buf, struct prefix *p); +int pim_encode_addr_ucast(uint8_t *buf, pim_addr addr); +int pim_encode_addr_ucast_prefix(uint8_t *buf, struct prefix *p);  int pim_encode_addr_group(uint8_t *buf, afi_t afi, int bidir, int scope, -			  struct in_addr group); +			  pim_addr group); -int pim_parse_addr_ucast(struct prefix *p, const uint8_t *buf, int buf_size); +int pim_parse_addr_ucast(pim_addr *out, const uint8_t *buf, int buf_size, +			 bool *wrong_af); +int pim_parse_addr_ucast_prefix(struct prefix *out, const uint8_t *buf, +				int buf_size);  int pim_parse_addr_group(pim_sgaddr *sg, const uint8_t *buf, int buf_size);  int pim_parse_addr_source(pim_sgaddr *sg, uint8_t *flags, const uint8_t *buf,  			  int buf_size);  | 
