mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-02 14:43:23 +00:00
vrrpd: include auth fields in v2 packet
Based on looking at other vendors, seems I misinterpreted the RFC - type 0 auth (no authentication) still requires the authentication fields to be present, just set to all zero. This should fix VRRPv2 interop with other vendors. Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
parent
8b28e459a1
commit
c2034b2550
@ -119,7 +119,7 @@ ssize_t vrrp_pkt_adver_build(struct vrrp_pkt **pkt, struct ipaddr *src,
|
|||||||
addrsz = IPADDRSZ(ips[0]);
|
addrsz = IPADDRSZ(ips[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pktsize = VRRP_PKT_SIZE(v6 ? AF_INET6 : AF_INET, numip);
|
size_t pktsize = VRRP_PKT_SIZE(v6 ? AF_INET6 : AF_INET, version, numip);
|
||||||
*pkt = XCALLOC(MTYPE_VRRP_PKT, pktsize);
|
*pkt = XCALLOC(MTYPE_VRRP_PKT, pktsize);
|
||||||
|
|
||||||
(*pkt)->hdr.vertype |= version << 4;
|
(*pkt)->hdr.vertype |= version << 4;
|
||||||
@ -283,9 +283,10 @@ ssize_t vrrp_pkt_parse_datagram(int family, int version, struct msghdr *m,
|
|||||||
VRRP_PKT_VCHECK(((*pkt)->hdr.vertype & 0x0F) == 1, "Bad type %" PRIu8,
|
VRRP_PKT_VCHECK(((*pkt)->hdr.vertype & 0x0F) == 1, "Bad type %" PRIu8,
|
||||||
(*pkt)->hdr.vertype & 0x0f);
|
(*pkt)->hdr.vertype & 0x0f);
|
||||||
|
|
||||||
/* # addresses check */
|
/* Exact size check */
|
||||||
size_t ves = VRRP_PKT_SIZE(family, (*pkt)->hdr.naddr);
|
size_t ves = VRRP_PKT_SIZE(family, pktver, (*pkt)->hdr.naddr);
|
||||||
VRRP_PKT_VCHECK(pktsize == ves, "Packet has incorrect # addresses");
|
VRRP_PKT_VCHECK(pktsize == ves, "Packet has incorrect # addresses%s",
|
||||||
|
pktver == 2 ? " or missing auth fields" : "");
|
||||||
|
|
||||||
/* auth type check */
|
/* auth type check */
|
||||||
if (version == 2)
|
if (version == 2)
|
||||||
|
@ -70,6 +70,10 @@ struct vrrp_pkt {
|
|||||||
* When used, this is actually an array of one or the other, not an
|
* When used, this is actually an array of one or the other, not an
|
||||||
* array of union. If N v4 addresses are stored then
|
* array of union. If N v4 addresses are stored then
|
||||||
* sizeof(addrs) == N * sizeof(struct in_addr).
|
* sizeof(addrs) == N * sizeof(struct in_addr).
|
||||||
|
*
|
||||||
|
* Under v2, the last 2 entries in this array are the authentication
|
||||||
|
* data fields. We don't support auth in v2 so these are always just 8
|
||||||
|
* bytes of 0x00.
|
||||||
*/
|
*/
|
||||||
union {
|
union {
|
||||||
struct in_addr v4;
|
struct in_addr v4;
|
||||||
@ -77,17 +81,18 @@ struct vrrp_pkt {
|
|||||||
} addrs[];
|
} addrs[];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
#define VRRP_PKT_SIZE(_f, _naddr) \
|
#define VRRP_PKT_SIZE(_f, _ver, _naddr) \
|
||||||
({ \
|
({ \
|
||||||
size_t _asz = ((_f) == AF_INET) ? sizeof(struct in_addr) \
|
size_t _asz = ((_f) == AF_INET) ? sizeof(struct in_addr) \
|
||||||
: sizeof(struct in6_addr); \
|
: sizeof(struct in6_addr); \
|
||||||
sizeof(struct vrrp_hdr) + (_asz * (_naddr)); \
|
size_t _auth = 2 * sizeof(uint32_t) * (3 - (_ver)); \
|
||||||
|
sizeof(struct vrrp_hdr) + (_asz * (_naddr)) + _auth; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define VRRP_MIN_PKT_SIZE_V4 VRRP_PKT_SIZE(AF_INET, 1)
|
#define VRRP_MIN_PKT_SIZE_V4 VRRP_PKT_SIZE(AF_INET, 3, 1)
|
||||||
#define VRRP_MAX_PKT_SIZE_V4 VRRP_PKT_SIZE(AF_INET, 255)
|
#define VRRP_MAX_PKT_SIZE_V4 VRRP_PKT_SIZE(AF_INET, 2, 255)
|
||||||
#define VRRP_MIN_PKT_SIZE_V6 VRRP_PKT_SIZE(AF_INET6, 1)
|
#define VRRP_MIN_PKT_SIZE_V6 VRRP_PKT_SIZE(AF_INET6, 3, 1)
|
||||||
#define VRRP_MAX_PKT_SIZE_V6 VRRP_PKT_SIZE(AF_INET6, 255)
|
#define VRRP_MAX_PKT_SIZE_V6 VRRP_PKT_SIZE(AF_INET6, 3, 255)
|
||||||
|
|
||||||
#define VRRP_MIN_PKT_SIZE VRRP_MIN_PKT_SIZE_V4
|
#define VRRP_MIN_PKT_SIZE VRRP_MIN_PKT_SIZE_V4
|
||||||
#define VRRP_MAX_PKT_SIZE VRRP_MAX_PKT_SIZE_V6
|
#define VRRP_MAX_PKT_SIZE VRRP_MAX_PKT_SIZE_V6
|
||||||
|
Loading…
Reference in New Issue
Block a user