diff options
Diffstat (limited to 'vrrpd/vrrp_packet.c')
| -rw-r--r-- | vrrpd/vrrp_packet.c | 24 | 
1 files changed, 19 insertions, 5 deletions
diff --git a/vrrpd/vrrp_packet.c b/vrrpd/vrrp_packet.c index 5010b4701d..8147da68e0 100644 --- a/vrrpd/vrrp_packet.c +++ b/vrrpd/vrrp_packet.c @@ -26,6 +26,7 @@  #include "lib/ipaddr.h"  #include "lib/memory.h" +#include "vrrp.h"  #include "vrrp_packet.h"  /* clang-format off */ @@ -49,8 +50,8 @@ const char *vrrp_packet_names[16] = {  };  /* clang-format on */ -ssize_t vrrp_pkt_build(struct vrrp_pkt **pkt, uint8_t vrid, uint8_t prio, -		       uint16_t max_adver_int, uint8_t numip, +ssize_t vrrp_pkt_build(struct vrrp_pkt **pkt, struct ipaddr *src, uint8_t vrid, +		       uint8_t prio, uint16_t max_adver_int, uint8_t numip,  		       struct ipaddr **ips)  {  	bool v6 = IS_IPADDR_V6(ips[0]); @@ -72,11 +73,24 @@ ssize_t vrrp_pkt_build(struct vrrp_pkt **pkt, uint8_t vrid, uint8_t prio,  		memcpy(aptr, &ips[i]->ip.addr, addrsz);  		aptr += addrsz;  	} +  	(*pkt)->hdr.chksum = 0; -	/* FIXME: v6 checksum */ -	uint16_t chksum = in_cksum(*pkt, pktsize); -	(*pkt)->hdr.chksum = htons(chksum); +	if (v6) { +		struct ipv6_ph ph = {}; +		ph.src = src->ipaddr_v6; +		inet_pton(AF_INET6, VRRP_MCASTV6_GROUP_STR, &ph.dst); +		ph.ulpl = htons(pktsize); +		ph.next_hdr = 112; +		(*pkt)->hdr.chksum = in_cksum_with_ph6(&ph, *pkt, pktsize); +	} else { +		struct ipv4_ph ph = {}; +		ph.src = src->ipaddr_v4; +		inet_pton(AF_INET, VRRP_MCASTV4_GROUP_STR, &ph.dst); +		ph.proto = 112; +		ph.len = htons(pktsize); +		(*pkt)->hdr.chksum = in_cksum_with_ph4(&ph, *pkt, pktsize); +	}  	return pktsize;  }  | 
