mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-12 11:18:59 +00:00
vrrpd: bind sockets to interfaces
Bind Rx socket to inbound interface. Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
parent
7e205b4a8f
commit
b523b2419e
106
vrrpd/vrrp.c
106
vrrpd/vrrp.c
@ -602,8 +602,6 @@ static int vrrp_bind_to_primary_connected(struct vrrp_router *r)
|
|||||||
* all transmitted IPvX packets
|
* all transmitted IPvX packets
|
||||||
* - Requests the kernel to deliver IPv6 header values needed to validate VRRP
|
* - Requests the kernel to deliver IPv6 header values needed to validate VRRP
|
||||||
* packets
|
* packets
|
||||||
* - FIXME: Binds the Tx socket to the first address on the macvlan
|
|
||||||
* subinterface.
|
|
||||||
*
|
*
|
||||||
* If any of the above fail, the sockets are closed. The only exception is if
|
* If any of the above fail, the sockets are closed. The only exception is if
|
||||||
* the TTL / Hop Limit settings fail; these are logged, but configuration
|
* the TTL / Hop Limit settings fail; these are logged, but configuration
|
||||||
@ -661,12 +659,58 @@ static int vrrp_socket(struct vrrp_router *r)
|
|||||||
r->vr->vrid);
|
r->vr->vrid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Bind Rx socket to exact interface */
|
||||||
|
vrrp_privs.change(ZPRIVS_RAISE);
|
||||||
|
{
|
||||||
|
ret = setsockopt(r->sock_rx, SOL_SOCKET,
|
||||||
|
SO_BINDTODEVICE, r->vr->ifp->name,
|
||||||
|
strlen(r->vr->ifp->name));
|
||||||
|
}
|
||||||
|
vrrp_privs.change(ZPRIVS_LOWER);
|
||||||
|
if (ret) {
|
||||||
|
zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
||||||
|
"Failed to bind Rx socket to %s: %s",
|
||||||
|
r->vr->vrid, r->vr->ifp->name,
|
||||||
|
safe_strerror(errno));
|
||||||
|
failed = true;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
zlog_info(VRRP_LOGPFX VRRP_LOGPFX_VRID "Bound Rx socket to %s",
|
||||||
|
r->vr->vrid, r->vr->ifp->name);
|
||||||
|
|
||||||
|
/* Bind Rx socket to v4 multicast address */
|
||||||
|
struct sockaddr_in sa = {0};
|
||||||
|
sa.sin_family = AF_INET;
|
||||||
|
sa.sin_addr.s_addr = htonl(VRRP_MCASTV4_GROUP);
|
||||||
|
if (bind(r->sock_rx, (struct sockaddr *)&sa, sizeof(sa))) {
|
||||||
|
zlog_err(
|
||||||
|
VRRP_LOGPFX VRRP_LOGPFX_VRID
|
||||||
|
"Failed to bind Rx socket to VRRP %s multicast group: %s",
|
||||||
|
r->vr->vrid, family2str(r->family),
|
||||||
|
safe_strerror(errno));
|
||||||
|
failed = true;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
zlog_info(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
||||||
|
"Bound Rx socket to VRRP %s multicast group",
|
||||||
|
r->vr->vrid, family2str(r->family));
|
||||||
|
|
||||||
/* Join Rx socket to VRRP IPv4 multicast group */
|
/* Join Rx socket to VRRP IPv4 multicast group */
|
||||||
struct connected *c = listhead(r->vr->ifp->connected)->data;
|
struct connected *c = listhead(r->vr->ifp->connected)->data;
|
||||||
struct in_addr v4 = c->address->u.prefix4;
|
struct in_addr v4 = c->address->u.prefix4;
|
||||||
ret = setsockopt_ipv4_multicast(r->sock_rx, IP_ADD_MEMBERSHIP,
|
ret = setsockopt_ipv4_multicast(r->sock_rx, IP_ADD_MEMBERSHIP,
|
||||||
v4, htonl(VRRP_MCASTV4_GROUP),
|
v4, htonl(VRRP_MCASTV4_GROUP),
|
||||||
r->vr->ifp->ifindex);
|
r->vr->ifp->ifindex);
|
||||||
|
if (ret < 0) {
|
||||||
|
zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
||||||
|
"Failed to join VRRP %s multicast group",
|
||||||
|
r->vr->vrid, family2str(r->family));
|
||||||
|
failed = true;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
zlog_info(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
||||||
|
"Joined %s VRRP multicast group",
|
||||||
|
r->vr->vrid, family2str(r->family));
|
||||||
|
|
||||||
/* Set outgoing interface for advertisements */
|
/* Set outgoing interface for advertisements */
|
||||||
struct ip_mreqn mreqn = {};
|
struct ip_mreqn mreqn = {};
|
||||||
@ -702,6 +746,42 @@ static int vrrp_socket(struct vrrp_router *r)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Bind Rx socket to exact interface */
|
||||||
|
vrrp_privs.change(ZPRIVS_RAISE);
|
||||||
|
{
|
||||||
|
ret = setsockopt(r->sock_rx, SOL_SOCKET,
|
||||||
|
SO_BINDTODEVICE, r->vr->ifp->name,
|
||||||
|
strlen(r->vr->ifp->name));
|
||||||
|
}
|
||||||
|
vrrp_privs.change(ZPRIVS_LOWER);
|
||||||
|
if (ret) {
|
||||||
|
zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
||||||
|
"Failed to bind Rx socket to %s: %s",
|
||||||
|
r->vr->vrid, r->vr->ifp->name,
|
||||||
|
safe_strerror(errno));
|
||||||
|
failed = true;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
zlog_info(VRRP_LOGPFX VRRP_LOGPFX_VRID "Bound Rx socket to %s",
|
||||||
|
r->vr->vrid, r->vr->ifp->name);
|
||||||
|
|
||||||
|
/* Bind Rx socket to v6 multicast address */
|
||||||
|
struct sockaddr_in6 sa = {0};
|
||||||
|
sa.sin6_family = AF_INET6;
|
||||||
|
inet_pton(AF_INET6, VRRP_MCASTV6_GROUP_STR, &sa.sin6_addr);
|
||||||
|
if (bind(r->sock_rx, (struct sockaddr *)&sa, sizeof(sa))) {
|
||||||
|
zlog_err(
|
||||||
|
VRRP_LOGPFX VRRP_LOGPFX_VRID
|
||||||
|
"Failed to bind Rx socket to VRRP %s multicast group: %s",
|
||||||
|
r->vr->vrid, family2str(r->family),
|
||||||
|
safe_strerror(errno));
|
||||||
|
failed = true;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
zlog_info(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
||||||
|
"Bound Rx socket to VRRP %s multicast group",
|
||||||
|
r->vr->vrid, family2str(r->family));
|
||||||
|
|
||||||
/* Join VRRP IPv6 multicast group */
|
/* Join VRRP IPv6 multicast group */
|
||||||
struct ipv6_mreq mreq;
|
struct ipv6_mreq mreq;
|
||||||
inet_pton(AF_INET6, VRRP_MCASTV6_GROUP_STR,
|
inet_pton(AF_INET6, VRRP_MCASTV6_GROUP_STR,
|
||||||
@ -709,6 +789,16 @@ static int vrrp_socket(struct vrrp_router *r)
|
|||||||
mreq.ipv6mr_interface = r->vr->ifp->ifindex;
|
mreq.ipv6mr_interface = r->vr->ifp->ifindex;
|
||||||
ret = setsockopt(r->sock_rx, IPPROTO_IPV6, IPV6_JOIN_GROUP,
|
ret = setsockopt(r->sock_rx, IPPROTO_IPV6, IPV6_JOIN_GROUP,
|
||||||
&mreq, sizeof(mreq));
|
&mreq, sizeof(mreq));
|
||||||
|
if (ret < 0) {
|
||||||
|
zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
||||||
|
"Failed to join VRRP %s multicast group",
|
||||||
|
r->vr->vrid, family2str(r->family));
|
||||||
|
failed = true;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
zlog_info(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
||||||
|
"Joined %s VRRP multicast group",
|
||||||
|
r->vr->vrid, family2str(r->family));
|
||||||
|
|
||||||
/* Set outgoing interface for advertisements */
|
/* Set outgoing interface for advertisements */
|
||||||
ret = setsockopt(r->sock_tx, IPPROTO_IPV6, IPV6_MULTICAST_IF,
|
ret = setsockopt(r->sock_tx, IPPROTO_IPV6, IPV6_MULTICAST_IF,
|
||||||
@ -726,18 +816,6 @@ static int vrrp_socket(struct vrrp_router *r)
|
|||||||
r->vr->vrid, r->mvl_ifp->name);
|
r->vr->vrid, r->mvl_ifp->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0) {
|
|
||||||
zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
|
||||||
"Failed to join VRRP %s multicast group",
|
|
||||||
r->vr->vrid, family2str(r->family));
|
|
||||||
failed = true;
|
|
||||||
goto done;
|
|
||||||
} else {
|
|
||||||
zlog_info(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
|
||||||
"Joined %s VRRP multicast group",
|
|
||||||
r->vr->vrid, family2str(r->family));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bind Tx socket to link-local address */
|
/* Bind Tx socket to link-local address */
|
||||||
if (vrrp_bind_to_primary_connected(r) < 0) {
|
if (vrrp_bind_to_primary_connected(r) < 0) {
|
||||||
failed = true;
|
failed = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user