From: Quentin Young Date: Fri, 1 Feb 2019 21:22:18 +0000 (+0000) Subject: vrrpd: use address cmp for priority tiebreak X-Git-Tag: base_7.2~330^2~108 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=0f1f98e8377b624b0c67e4ca845fb142d4db7812;p=matthieu%2Ffrr.git vrrpd: use address cmp for priority tiebreak Signed-off-by: Quentin Young --- diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c index 411c3c7e7b..2605a84dee 100644 --- a/vrrpd/vrrp.c +++ b/vrrpd/vrrp.c @@ -464,9 +464,25 @@ static void vrrp_send_advertisement(struct vrrp_router *r) * However, we have not validated whether the VRID is correct for this virtual * router, nor whether the priority is correct (i.e. is not 255 when we are the * address owner). + * + * r + * VRRP Router associated with the socket this advertisement was received on + * + * src + * Source address of sender + * + * pkt + * The advertisement they sent + * + * pktsize + * Size of advertisement + * + * Returns: + * -1 if advertisement is invalid + * 0 otherwise */ -static int vrrp_recv_advertisement(struct vrrp_router *r, struct vrrp_pkt *pkt, - size_t pktsize) +static int vrrp_recv_advertisement(struct vrrp_router *r, struct ipaddr *src, + struct vrrp_pkt *pkt, size_t pktsize) { char dumpbuf[BUFSIZ]; vrrp_pkt_adver_dump(dumpbuf, sizeof(dumpbuf), pkt); @@ -500,8 +516,14 @@ static int vrrp_recv_advertisement(struct vrrp_router *r, struct vrrp_pkt *pkt, r->addrs->count); } + int addrcmp; + size_t cmpsz = IS_IPADDR_V6(src) ? sizeof(struct in6_addr) + : sizeof(struct in_addr); + switch (r->fsm.state) { case VRRP_STATE_MASTER: + addrcmp = memcmp(&src->ip, &r->src.ip, cmpsz); + if (pkt->hdr.priority == 0) { vrrp_send_advertisement(r); THREAD_OFF(r->t_adver_timer); @@ -509,9 +531,8 @@ static int vrrp_recv_advertisement(struct vrrp_router *r, struct vrrp_pkt *pkt, master, vrrp_adver_timer_expire, r, r->vr->advertisement_interval * 10, &r->t_adver_timer); - /* FIXME: 6.4.3 mandates checking sender IP address */ - } else if (pkt->hdr.priority > r->priority) { - zlog_err("NOT IMPLEMENTED"); + } else if (pkt->hdr.priority > r->priority + || ((pkt->hdr.priority == r->priority) && addrcmp > 0)) { THREAD_OFF(r->t_adver_timer); r->master_adver_interval = ntohs(pkt->hdr.v3.adver_int); vrrp_recalculate_timers(r); @@ -606,7 +627,7 @@ static int vrrp_read(struct thread *thread) } else { zlog_debug(VRRP_LOGPFX VRRP_LOGPFX_VRID "Packet looks good", r->vr->vrid); - vrrp_recv_advertisement(r, pkt, pktsize); + vrrp_recv_advertisement(r, &src, pkt, pktsize); } resched = true;