mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 16:04:49 +00:00
Merge pull request #3467 from donaldsharp/kernel_socket_cleanup
Kernel socket cleanup
This commit is contained in:
commit
eefe8ab766
@ -918,6 +918,9 @@ void rtm_read(struct rt_msghdr *rtm)
|
|||||||
char ifname[INTERFACE_NAMSIZ + 1];
|
char ifname[INTERFACE_NAMSIZ + 1];
|
||||||
short ifnlen = 0;
|
short ifnlen = 0;
|
||||||
struct nexthop nh;
|
struct nexthop nh;
|
||||||
|
struct prefix p;
|
||||||
|
ifindex_t ifindex = 0;
|
||||||
|
afi_t afi;
|
||||||
|
|
||||||
zebra_flags = 0;
|
zebra_flags = 0;
|
||||||
|
|
||||||
@ -963,9 +966,14 @@ void rtm_read(struct rt_msghdr *rtm)
|
|||||||
nh.bh_type = BLACKHOLE_NULL;
|
nh.bh_type = BLACKHOLE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest.sa.sa_family == AF_INET) {
|
/*
|
||||||
struct prefix p;
|
* Ignore our own messages.
|
||||||
|
*/
|
||||||
|
if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (dest.sa.sa_family == AF_INET) {
|
||||||
|
afi = AFI_IP;
|
||||||
p.family = AF_INET;
|
p.family = AF_INET;
|
||||||
p.u.prefix4 = dest.sin.sin_addr;
|
p.u.prefix4 = dest.sin.sin_addr;
|
||||||
if (flags & RTF_HOST)
|
if (flags & RTF_HOST)
|
||||||
@ -973,146 +981,12 @@ void rtm_read(struct rt_msghdr *rtm)
|
|||||||
else
|
else
|
||||||
p.prefixlen = ip_masklen(mask.sin.sin_addr);
|
p.prefixlen = ip_masklen(mask.sin.sin_addr);
|
||||||
|
|
||||||
/* Catch self originated messages and match them against our
|
|
||||||
* current RIB.
|
|
||||||
* At the same time, ignore unconfirmed messages, they should be
|
|
||||||
* tracked
|
|
||||||
* by rtm_write() and kernel_rtm_ipv4().
|
|
||||||
*/
|
|
||||||
if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) {
|
|
||||||
char buf[PREFIX_STRLEN], gate_buf[INET_ADDRSTRLEN];
|
|
||||||
int ret;
|
|
||||||
if (!IS_ZEBRA_DEBUG_RIB)
|
|
||||||
return;
|
|
||||||
ret = rib_lookup_ipv4_route((struct prefix_ipv4 *)&p,
|
|
||||||
&gate, VRF_DEFAULT);
|
|
||||||
prefix2str(&p, buf, sizeof(buf));
|
|
||||||
switch (rtm->rtm_type) {
|
|
||||||
case RTM_ADD:
|
|
||||||
case RTM_GET:
|
|
||||||
case RTM_CHANGE:
|
|
||||||
/* The kernel notifies us about a new route in
|
|
||||||
FIB created by us.
|
|
||||||
Do we have a correspondent entry in our RIB?
|
|
||||||
*/
|
|
||||||
switch (ret) {
|
|
||||||
case ZEBRA_RIB_NOTFOUND:
|
|
||||||
zlog_debug(
|
|
||||||
"%s: %s %s: desync: RR isn't yet in RIB, while already in FIB",
|
|
||||||
__func__,
|
|
||||||
lookup_msg(rtm_type_str,
|
|
||||||
rtm->rtm_type, NULL),
|
|
||||||
buf);
|
|
||||||
break;
|
|
||||||
case ZEBRA_RIB_FOUND_CONNECTED:
|
|
||||||
case ZEBRA_RIB_FOUND_NOGATE:
|
|
||||||
inet_ntop(AF_INET, &gate.sin.sin_addr,
|
|
||||||
gate_buf, INET_ADDRSTRLEN);
|
|
||||||
zlog_debug(
|
|
||||||
"%s: %s %s: desync: RR is in RIB, but gate differs (ours is %s)",
|
|
||||||
__func__,
|
|
||||||
lookup_msg(rtm_type_str,
|
|
||||||
rtm->rtm_type, NULL),
|
|
||||||
buf, gate_buf);
|
|
||||||
break;
|
|
||||||
case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR
|
|
||||||
*/
|
|
||||||
zlog_debug(
|
|
||||||
"%s: %s %s: done Ok", __func__,
|
|
||||||
lookup_msg(rtm_type_str,
|
|
||||||
rtm->rtm_type, NULL),
|
|
||||||
buf);
|
|
||||||
rib_lookup_and_dump(
|
|
||||||
(struct prefix_ipv4 *)&p,
|
|
||||||
VRF_DEFAULT);
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RTM_DELETE:
|
|
||||||
/* The kernel notifies us about a route deleted
|
|
||||||
by us. Do we still
|
|
||||||
have it in the RIB? Do we have anything
|
|
||||||
instead? */
|
|
||||||
switch (ret) {
|
|
||||||
case ZEBRA_RIB_FOUND_EXACT:
|
|
||||||
zlog_debug(
|
|
||||||
"%s: %s %s: desync: RR is still in RIB, while already not in FIB",
|
|
||||||
__func__,
|
|
||||||
lookup_msg(rtm_type_str,
|
|
||||||
rtm->rtm_type, NULL),
|
|
||||||
buf);
|
|
||||||
rib_lookup_and_dump(
|
|
||||||
(struct prefix_ipv4 *)&p,
|
|
||||||
VRF_DEFAULT);
|
|
||||||
break;
|
|
||||||
case ZEBRA_RIB_FOUND_CONNECTED:
|
|
||||||
case ZEBRA_RIB_FOUND_NOGATE:
|
|
||||||
zlog_debug(
|
|
||||||
"%s: %s %s: desync: RR is still in RIB, plus gate differs",
|
|
||||||
__func__,
|
|
||||||
lookup_msg(rtm_type_str,
|
|
||||||
rtm->rtm_type, NULL),
|
|
||||||
buf);
|
|
||||||
rib_lookup_and_dump(
|
|
||||||
(struct prefix_ipv4 *)&p,
|
|
||||||
VRF_DEFAULT);
|
|
||||||
break;
|
|
||||||
case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */
|
|
||||||
zlog_debug(
|
|
||||||
"%s: %s %s: done Ok", __func__,
|
|
||||||
lookup_msg(rtm_type_str,
|
|
||||||
rtm->rtm_type, NULL),
|
|
||||||
buf);
|
|
||||||
rib_lookup_and_dump(
|
|
||||||
(struct prefix_ipv4 *)&p,
|
|
||||||
VRF_DEFAULT);
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
zlog_debug(
|
|
||||||
"%s: %s: warning: loopback RTM of type %s received",
|
|
||||||
__func__, buf,
|
|
||||||
lookup_msg(rtm_type_str, rtm->rtm_type,
|
|
||||||
NULL));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Change, delete the old prefix, we have no further information
|
|
||||||
* to specify the route really
|
|
||||||
*/
|
|
||||||
if (rtm->rtm_type == RTM_CHANGE)
|
|
||||||
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
|
||||||
NULL, 0, 0, 0, true);
|
|
||||||
|
|
||||||
if (!nh.type) {
|
if (!nh.type) {
|
||||||
nh.type = NEXTHOP_TYPE_IPV4;
|
nh.type = NEXTHOP_TYPE_IPV4;
|
||||||
nh.gate.ipv4 = gate.sin.sin_addr;
|
nh.gate.ipv4 = gate.sin.sin_addr;
|
||||||
}
|
}
|
||||||
|
} else if (dest.sa.sa_family == AF_INET6) {
|
||||||
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|
afi = AFI_IP6;
|
||||||
|| rtm->rtm_type == RTM_CHANGE)
|
|
||||||
rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
|
||||||
&nh, 0, 0, 0, 0, 0);
|
|
||||||
else
|
|
||||||
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
|
||||||
&nh, 0, 0, 0, true);
|
|
||||||
}
|
|
||||||
if (dest.sa.sa_family == AF_INET6) {
|
|
||||||
/* One day we might have a debug section here like one in the
|
|
||||||
* IPv4 case above. Just ignore own messages at the moment.
|
|
||||||
*/
|
|
||||||
if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)
|
|
||||||
return;
|
|
||||||
struct prefix p;
|
|
||||||
ifindex_t ifindex = 0;
|
|
||||||
|
|
||||||
p.family = AF_INET6;
|
p.family = AF_INET6;
|
||||||
p.u.prefix6 = dest.sin6.sin6_addr;
|
p.u.prefix6 = dest.sin6.sin6_addr;
|
||||||
if (flags & RTF_HOST)
|
if (flags & RTF_HOST)
|
||||||
@ -1127,31 +1001,29 @@ void rtm_read(struct rt_msghdr *rtm)
|
|||||||
}
|
}
|
||||||
#endif /* KAME */
|
#endif /* KAME */
|
||||||
|
|
||||||
/* CHANGE: delete the old prefix, we have no further information
|
|
||||||
* to specify the route really
|
|
||||||
*/
|
|
||||||
if (rtm->rtm_type == RTM_CHANGE)
|
|
||||||
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
|
||||||
NULL, 0, 0, 0, true);
|
|
||||||
|
|
||||||
if (!nh.type) {
|
if (!nh.type) {
|
||||||
nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
|
nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
|
||||||
: NEXTHOP_TYPE_IPV6;
|
: NEXTHOP_TYPE_IPV6;
|
||||||
nh.gate.ipv6 = gate.sin6.sin6_addr;
|
nh.gate.ipv6 = gate.sin6.sin6_addr;
|
||||||
nh.ifindex = ifindex;
|
nh.ifindex = ifindex;
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
return;
|
||||||
|
|
||||||
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|
/*
|
||||||
|| rtm->rtm_type == RTM_CHANGE)
|
* CHANGE: delete the old prefix, we have no further information
|
||||||
rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
* to specify the route really
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
*/
|
||||||
&nh, 0, 0, 0, 0, 0);
|
if (rtm->rtm_type == RTM_CHANGE)
|
||||||
else
|
rib_delete(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
|
||||||
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
0, zebra_flags, &p, NULL, NULL, 0, 0, 0, true);
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|
||||||
&nh, 0, 0, 0, true);
|
|| rtm->rtm_type == RTM_CHANGE)
|
||||||
}
|
rib_add(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
|
||||||
|
zebra_flags, &p, NULL, &nh, 0, 0, 0, 0, 0);
|
||||||
|
else
|
||||||
|
rib_delete(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
|
||||||
|
0, zebra_flags, &p, NULL, &nh, 0, 0, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interface function for the kernel routing table updates. Support
|
/* Interface function for the kernel routing table updates. Support
|
||||||
|
@ -282,8 +282,6 @@ extern enum multicast_mode multicast_mode_ipv4_get(void);
|
|||||||
extern void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id);
|
extern void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id);
|
||||||
extern void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id);
|
extern void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id);
|
||||||
|
|
||||||
extern int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
|
|
||||||
vrf_id_t vrf_id);
|
|
||||||
#define ZEBRA_RIB_LOOKUP_ERROR -1
|
#define ZEBRA_RIB_LOOKUP_ERROR -1
|
||||||
#define ZEBRA_RIB_FOUND_EXACT 0
|
#define ZEBRA_RIB_FOUND_EXACT 0
|
||||||
#define ZEBRA_RIB_FOUND_NOGATE 1
|
#define ZEBRA_RIB_FOUND_NOGATE 1
|
||||||
|
@ -808,84 +808,6 @@ struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This clone function, unlike its original rib_lookup_ipv4(), checks
|
|
||||||
* if specified IPv4 route record (prefix/mask -> gate) exists in
|
|
||||||
* the whole RIB and has ROUTE_ENTRY_SELECTED_FIB set.
|
|
||||||
*
|
|
||||||
* Return values:
|
|
||||||
* -1: error
|
|
||||||
* 0: exact match found
|
|
||||||
* 1: a match was found with a different gate
|
|
||||||
* 2: connected route found
|
|
||||||
* 3: no matches found
|
|
||||||
*/
|
|
||||||
int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
|
|
||||||
vrf_id_t vrf_id)
|
|
||||||
{
|
|
||||||
struct route_table *table;
|
|
||||||
struct route_node *rn;
|
|
||||||
struct route_entry *match = NULL;
|
|
||||||
struct nexthop *nexthop;
|
|
||||||
int nexthops_active;
|
|
||||||
rib_dest_t *dest;
|
|
||||||
|
|
||||||
/* Lookup table. */
|
|
||||||
table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
|
|
||||||
if (!table)
|
|
||||||
return ZEBRA_RIB_LOOKUP_ERROR;
|
|
||||||
|
|
||||||
/* Scan the RIB table for exactly matching RIB entry. */
|
|
||||||
rn = route_node_lookup(table, (struct prefix *)p);
|
|
||||||
|
|
||||||
/* No route for this prefix. */
|
|
||||||
if (!rn)
|
|
||||||
return ZEBRA_RIB_NOTFOUND;
|
|
||||||
|
|
||||||
/* Unlock node. */
|
|
||||||
route_unlock_node(rn);
|
|
||||||
dest = rib_dest_from_rnode(rn);
|
|
||||||
|
|
||||||
/* Find out if a "selected" RR for the discovered RIB entry exists ever.
|
|
||||||
*/
|
|
||||||
if (dest && dest->selected_fib
|
|
||||||
&& !CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED))
|
|
||||||
match = dest->selected_fib;
|
|
||||||
|
|
||||||
/* None such found :( */
|
|
||||||
if (!match)
|
|
||||||
return ZEBRA_RIB_NOTFOUND;
|
|
||||||
|
|
||||||
if (match->type == ZEBRA_ROUTE_CONNECT)
|
|
||||||
return ZEBRA_RIB_FOUND_CONNECTED;
|
|
||||||
|
|
||||||
/* Ok, we have a cood candidate, let's check it's nexthop list... */
|
|
||||||
nexthops_active = 0;
|
|
||||||
for (ALL_NEXTHOPS(match->ng, nexthop))
|
|
||||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
|
|
||||||
nexthops_active = 1;
|
|
||||||
if (nexthop->gate.ipv4.s_addr == sockunion2ip(qgate))
|
|
||||||
return ZEBRA_RIB_FOUND_EXACT;
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB) {
|
|
||||||
char gate_buf[INET_ADDRSTRLEN],
|
|
||||||
qgate_buf[INET_ADDRSTRLEN];
|
|
||||||
inet_ntop(AF_INET, &nexthop->gate.ipv4.s_addr,
|
|
||||||
gate_buf, INET_ADDRSTRLEN);
|
|
||||||
inet_ntop(AF_INET, &sockunion2ip(qgate),
|
|
||||||
qgate_buf, INET_ADDRSTRLEN);
|
|
||||||
zlog_debug("%s: qgate == %s, %s == %s",
|
|
||||||
__func__, qgate_buf,
|
|
||||||
nexthop->rparent ? "rgate" : "gate",
|
|
||||||
gate_buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nexthops_active)
|
|
||||||
return ZEBRA_RIB_FOUND_NOGATE;
|
|
||||||
|
|
||||||
return ZEBRA_RIB_NOTFOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define RIB_SYSTEM_ROUTE(R) \
|
#define RIB_SYSTEM_ROUTE(R) \
|
||||||
((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
|
((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user