mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-29 14:40:47 +00:00
vrrpd: compute VRRPv3 checksum
Correctly compute VRRPv3 checksum. Pseudoheaders are used for both IPv4 and IPv6. Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
parent
17b48d7d11
commit
8071d5c3e3
12
vrrpd/vrrp.c
12
vrrpd/vrrp.c
@ -327,7 +327,7 @@ static void vrrp_send_advertisement(struct vrrp_router *r)
|
||||
|
||||
list_to_array(r->addrs, (void **)addrs, r->addrs->count);
|
||||
|
||||
pktlen = vrrp_pkt_build(&pkt, r->vr->vrid, r->priority,
|
||||
pktlen = vrrp_pkt_build(&pkt, &r->src, r->vr->vrid, r->priority,
|
||||
r->vr->advertisement_interval, r->addrs->count,
|
||||
(struct ipaddr **)&addrs);
|
||||
|
||||
@ -347,8 +347,8 @@ static void vrrp_send_advertisement(struct vrrp_router *r)
|
||||
|
||||
if (sent < 0) {
|
||||
zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
||||
"Failed to send VRRP Advertisement",
|
||||
r->vr->vrid);
|
||||
"Failed to send VRRP Advertisement: %s",
|
||||
r->vr->vrid, safe_strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
@ -523,6 +523,8 @@ done:
|
||||
* router's interface and binds the Tx socket of the VRRP router to that
|
||||
* address.
|
||||
*
|
||||
* Also sets src field of vrrp_router.
|
||||
*
|
||||
* r
|
||||
* VRRP router to operate on
|
||||
*
|
||||
@ -559,10 +561,14 @@ static int vrrp_bind_to_primary_connected(struct vrrp_router *r)
|
||||
|
||||
switch (r->family) {
|
||||
case AF_INET:
|
||||
r->src.ipa_type = IPADDR_V4;
|
||||
r->src.ipaddr_v4 = c->address->u.prefix4;
|
||||
su.sin.sin_family = AF_INET;
|
||||
su.sin.sin_addr = c->address->u.prefix4;
|
||||
break;
|
||||
case AF_INET6:
|
||||
r->src.ipa_type = IPADDR_V6;
|
||||
r->src.ipaddr_v6 = c->address->u.prefix6;
|
||||
su.sin6.sin6_family = AF_INET6;
|
||||
su.sin6.sin6_scope_id = ifp->ifindex;
|
||||
su.sin6.sin6_addr = c->address->u.prefix6;
|
||||
|
@ -75,6 +75,9 @@ struct vrrp_router {
|
||||
/* macvlan interface */
|
||||
struct interface *mvl_ifp;
|
||||
|
||||
/* Source address for advertisements */
|
||||
struct ipaddr src;
|
||||
|
||||
/* Socket read buffer */
|
||||
uint8_t ibuf[IP_MAXPACKET];
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -115,8 +115,8 @@ struct vrrp_pkt {
|
||||
* array of pointer to either struct in_addr (v6 = false) or struct in6_addr
|
||||
* (v6 = true)
|
||||
*/
|
||||
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);
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user