Ignore silently VRRP packet with a different VRID. Thanks to Samuel Melrose (https://github.com/iamacarpet/)

This commit is contained in:
Arnaud ANDRE 2015-11-06 13:03:26 +01:00
parent c83dbd0618
commit f62f405f58
3 changed files with 33 additions and 27 deletions

View file

@ -252,10 +252,11 @@ int vrrp_net_vip_set(struct vrrp_net *vnet, const char *ip)
/** /**
* vrrp_net_listen() - Wait for a VRRP pkt on vnet->socket * vrrp_net_listen() - Wait for a VRRP pkt on vnet->socket
* *
* @return TIMER if current timer is expired * @return vrrp_event_t
* @return PKT else * TIMER if current timer is expired
* another event else
*/ */
int vrrp_net_listen(struct vrrp_net *vnet, struct vrrp *vrrp) vrrp_event_t vrrp_net_listen(struct vrrp_net *vnet, struct vrrp *vrrp)
{ {
struct vrrp_timer *vt; struct vrrp_timer *vt;
@ -308,13 +309,7 @@ int vrrp_net_listen(struct vrrp_net *vnet, struct vrrp *vrrp)
log_debug("vrid %d :: VRRP pkt received", vrrp->vrid); log_debug("vrid %d :: VRRP pkt received", vrrp->vrid);
/* check if received is valid or not */ /* check if received is valid or not */
if (vrrp_net_recv(vnet, vrrp) > 0) return vrrp_net_recv(vnet, vrrp);
return PKT;
else {
log_error("vrid %d :: %s", vrrp->vrid,
"Received an invalid packet");
return INVALID;
}
} }
else { /* Signal or pselect error */ else { /* Signal or pselect error */
if (errno == EINTR) { if (errno == EINTR) {
@ -342,9 +337,9 @@ static inline void vrrp_net_invalidate_buffer(struct vrrp_net *vnet)
/** /**
* vrrp_net_recv() - read and check a received VRRP pkt advertisement * vrrp_net_recv() - read and check a received VRRP pkt advertisement
* *
* @return len of VRRP pkt if valid, -1 if invalid * @return vrrp_pkt_t
*/ */
int vrrp_net_recv(struct vrrp_net *vnet, const struct vrrp *vrrp) vrrp_event_t vrrp_net_recv(struct vrrp_net *vnet, const struct vrrp *vrrp)
{ {
/* fetch pkt data received to buf */ /* fetch pkt data received to buf */
unsigned char buf[IP_MAXPACKET]; unsigned char buf[IP_MAXPACKET];
@ -408,6 +403,13 @@ int vrrp_net_recv(struct vrrp_net *vnet, const struct vrrp *vrrp)
return INVALID; return INVALID;
} }
/* check if VRID is the same as the current instance */
if (vrrpkt->vrid != vrrp->vrid) {
log_debug("vrid %d :: Invalid pkt - Invalid VRID %d",
vrrp->vrid, vrrpkt->vrid);
return VRID_MISMATCH;
}
/* verify VRRP checksum */ /* verify VRRP checksum */
int chksum = vrrpkt->chksum; /* save checksum */ int chksum = vrrpkt->chksum; /* save checksum */
if (vnet->adv_checksum(vnet, vrrpkt, &vnet->__pkt.s_ipx, if (vnet->adv_checksum(vnet, vrrpkt, &vnet->__pkt.s_ipx,
@ -420,13 +422,6 @@ int vrrp_net_recv(struct vrrp_net *vnet, const struct vrrp *vrrp)
/* restore checksum */ /* restore checksum */
vrrpkt->chksum = chksum; vrrpkt->chksum = chksum;
/* check if VRID is the same as the current instance */
if (vrrpkt->vrid != vrrp->vrid) {
log_info("vrid %d :: Invalid pkt - Invalid VRID %d",
vrrp->vrid, vrrpkt->vrid);
return INVALID;
}
/* local router is the IP address owner /* local router is the IP address owner
* (Priority equals 255) * (Priority equals 255)
*/ */
@ -490,7 +485,7 @@ int vrrp_net_recv(struct vrrp_net *vnet, const struct vrrp *vrrp)
/* pkt is valid, keep it in internal buffer */ /* pkt is valid, keep it in internal buffer */
memcpy(&vnet->__pkt.adv, vrrpkt, sizeof(struct vrrphdr)); memcpy(&vnet->__pkt.adv, vrrpkt, sizeof(struct vrrphdr));
return len; return PKT;
} }
/** /**

View file

@ -139,13 +139,16 @@ struct vrrp_net {
/** /**
* enum vrrp_ret - Return code used in vrrp_net_listen * enum vrrp_ret - Return code used in vrrp_net_listen
*/ */
enum vrrp_ret { enum _vrrp_event_type {
INVALID = -1, VRID_MISMATCH = -2, /* vrid mismatch */
PKT, /* valid packet received */ INVALID = -1, /* invalid pkt */
SIGNAL, /* signal catch */ PKT, /* valid packet */
TIMER /* timer expired */ SIGNAL, /* signal catch */
TIMER /* timer expired */
}; };
typedef enum _vrrp_event_type vrrp_event_t;
/* /*
* funcs * funcs
*/ */
@ -156,8 +159,8 @@ int vrrp_net_socket_xmit(struct vrrp_net *vnet);
int vrrp_net_vif_getaddr(struct vrrp_net *vnet); int vrrp_net_vif_getaddr(struct vrrp_net *vnet);
int vrrp_net_vif_mtu(struct vrrp_net *vnet); int vrrp_net_vif_mtu(struct vrrp_net *vnet);
int vrrp_net_vip_set(struct vrrp_net *vnet, const char *ip); int vrrp_net_vip_set(struct vrrp_net *vnet, const char *ip);
int vrrp_net_listen(struct vrrp_net *vnet, struct vrrp *vrrp); vrrp_event_t vrrp_net_listen(struct vrrp_net *vnet, struct vrrp *vrrp);
int vrrp_net_recv(struct vrrp_net *vnet, const struct vrrp *vrrp); vrrp_event_t vrrp_net_recv(struct vrrp_net *vnet, const struct vrrp *vrrp);
int vrrp_net_send(const struct vrrp_net *vnet, struct iovec *iov, size_t len); int vrrp_net_send(const struct vrrp_net *vnet, struct iovec *iov, size_t len);
#endif /* _VRRP_NET_ */ #endif /* _VRRP_NET_ */

View file

@ -143,6 +143,10 @@ int vrrp_state_backup(struct vrrp *vrrp, struct vrrp_net *vnet)
break; break;
case VRID_MISMATCH:
/* ignore VRRP pkt with different vrid */
break;
case INVALID: case INVALID:
log_warning("vrid %d :: %s %s, %s", vrrp->vrid, log_warning("vrid %d :: %s %s, %s", vrrp->vrid,
"receive an invalid advertisement packet from", "receive an invalid advertisement packet from",
@ -253,6 +257,10 @@ int vrrp_state_master(struct vrrp *vrrp, struct vrrp_net *vnet)
break; break;
case VRID_MISMATCH:
/* ignore VRRP pkt with different vrid */
break;
case INVALID: case INVALID:
log_warning("vrid %d :: invalid event", vrrp->vrid); log_warning("vrid %d :: invalid event", vrrp->vrid);
break; break;