mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-16 08:32:45 +00:00
This commit is contained in:
parent
8a92a8a00c
commit
5c610fafc4
@ -41,6 +41,7 @@
|
||||
#include "zebra/debug.h"
|
||||
#include "zebra/irdp.h"
|
||||
#include "zebra/zebra_ptm.h"
|
||||
#include "zebra/rt_netlink.h"
|
||||
|
||||
#define ZEBRA_PTM_SUPPORT
|
||||
|
||||
@ -528,6 +529,64 @@ if_delete_update (struct interface *ifp)
|
||||
ifp->ifindex = IFINDEX_INTERNAL;
|
||||
}
|
||||
|
||||
void
|
||||
ipv6_ll_address_to_mac (struct in6_addr *address, u_char *mac)
|
||||
{
|
||||
mac[0] = address->s6_addr[8];
|
||||
mac[0] &= ~0x02;
|
||||
mac[1] = address->s6_addr[9];
|
||||
mac[2] = address->s6_addr[10];
|
||||
mac[3] = address->s6_addr[13];
|
||||
mac[4] = address->s6_addr[14];
|
||||
mac[5] = address->s6_addr[15];
|
||||
}
|
||||
|
||||
void
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_update (struct interface *ifp,
|
||||
struct in6_addr *address,
|
||||
int add)
|
||||
{
|
||||
char buf[16] = "169.254.0.1";
|
||||
struct in_addr ipv4_ll;
|
||||
u_char mac[6];
|
||||
|
||||
inet_pton (AF_INET, buf, &ipv4_ll);
|
||||
|
||||
ipv6_ll_address_to_mac(address, mac);
|
||||
netlink_neigh_update (add ? RTM_NEWNEIGH : RTM_DELNEIGH,
|
||||
ifp->ifindex, ipv4_ll.s_addr, mac, 6);
|
||||
}
|
||||
|
||||
void
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (struct interface *ifp)
|
||||
{
|
||||
if (listhead(ifp->nbr_connected))
|
||||
{
|
||||
struct nbr_connected *nbr_connected;
|
||||
struct listnode *node;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp,
|
||||
&nbr_connected->address->u.prefix6,
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (struct interface *ifp)
|
||||
{
|
||||
if (listhead(ifp->nbr_connected))
|
||||
{
|
||||
struct nbr_connected *nbr_connected;
|
||||
struct listnode *node;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp,
|
||||
&nbr_connected->address->u.prefix6,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Interface is up. */
|
||||
void
|
||||
if_up (struct interface *ifp)
|
||||
@ -545,6 +604,7 @@ if_up (struct interface *ifp)
|
||||
}
|
||||
zebra_interface_up_update (ifp);
|
||||
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (ifp);
|
||||
|
||||
/* Install connected routes to the kernel. */
|
||||
if (ifp->connected)
|
||||
@ -597,6 +657,8 @@ if_down (struct interface *ifp)
|
||||
|
||||
/* Examine all static routes which direct to the interface. */
|
||||
rib_update ();
|
||||
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -213,6 +213,9 @@ struct zebra_if
|
||||
#endif /* SUNOS_5 */
|
||||
};
|
||||
|
||||
extern void if_nbr_ipv6ll_to_ipv4ll_neigh_update (struct interface *ifp,
|
||||
struct in6_addr *address, int add);
|
||||
extern void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (struct interface *ifp);
|
||||
extern void if_delete_update (struct interface *ifp);
|
||||
extern void if_add_update (struct interface *ifp);
|
||||
extern void if_up (struct interface *);
|
||||
|
@ -48,6 +48,11 @@ int kernel_address_delete_ipv4 (struct interface *a, struct connected *b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kernel_init (void) { return; }
|
||||
#ifdef HAVE_SYS_WEAK_ALIAS_PRAGMA
|
||||
#pragma weak route_read = kernel_init
|
||||
|
@ -1483,8 +1483,30 @@ _netlink_route_build_singlepath(
|
||||
size_t req_size,
|
||||
int cmd)
|
||||
{
|
||||
|
||||
if (rtmsg->rtm_family == AF_INET &&
|
||||
(nexthop->type == NEXTHOP_TYPE_IPV6
|
||||
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
|
||||
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX))
|
||||
{
|
||||
char buf[16] = "169.254.0.1";
|
||||
struct in_addr ipv4_ll;
|
||||
|
||||
inet_pton (AF_INET, buf, &ipv4_ll);
|
||||
rtmsg->rtm_flags |= RTNH_F_ONLINK;
|
||||
addattr_l (nlmsg, req_size, RTA_GATEWAY, &ipv4_ll, 4);
|
||||
addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(" 5549: _netlink_route_build_singlepath() (%s): "
|
||||
"nexthop via %s if %u",
|
||||
routedesc, buf, nexthop->ifindex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
|
||||
rtmsg->rtm_flags |= RTNH_F_ONLINK;
|
||||
|
||||
if (nexthop->type == NEXTHOP_TYPE_IPV4
|
||||
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
|
||||
{
|
||||
@ -1573,14 +1595,38 @@ _netlink_route_build_multipath(
|
||||
struct nexthop *nexthop,
|
||||
struct rtattr *rta,
|
||||
struct rtnexthop *rtnh,
|
||||
union g_addr **src
|
||||
)
|
||||
struct rtmsg *rtmsg,
|
||||
union g_addr **src)
|
||||
{
|
||||
rtnh->rtnh_len = sizeof (*rtnh);
|
||||
rtnh->rtnh_flags = 0;
|
||||
rtnh->rtnh_hops = 0;
|
||||
rta->rta_len += rtnh->rtnh_len;
|
||||
|
||||
if (rtmsg->rtm_family == AF_INET &&
|
||||
(nexthop->type == NEXTHOP_TYPE_IPV6
|
||||
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
|
||||
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX))
|
||||
{
|
||||
char buf[16] = "169.254.0.1";
|
||||
struct in_addr ipv4_ll;
|
||||
|
||||
inet_pton (AF_INET, buf, &ipv4_ll);
|
||||
bytelen = 4;
|
||||
rtnh->rtnh_flags |= RTNH_F_ONLINK;
|
||||
rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_GATEWAY,
|
||||
&ipv4_ll, bytelen);
|
||||
rtnh->rtnh_len += sizeof (struct rtattr) + bytelen;
|
||||
rtnh->rtnh_ifindex = nexthop->ifindex;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(" 5549: netlink_route_build_multipath() (%s): "
|
||||
"nexthop via %s if %u",
|
||||
routedesc, buf, nexthop->ifindex);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
|
||||
rtnh->rtnh_flags |= RTNH_F_ONLINK;
|
||||
|
||||
@ -1683,6 +1729,32 @@ _netlink_route_debug(
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen)
|
||||
{
|
||||
struct {
|
||||
struct nlmsghdr n;
|
||||
struct ndmsg ndm;
|
||||
char buf[256];
|
||||
} req;
|
||||
|
||||
memset(&req.n, 0, sizeof(req.n));
|
||||
memset(&req.ndm, 0, sizeof(req.ndm));
|
||||
|
||||
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
|
||||
req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
|
||||
req.n.nlmsg_type = cmd; //RTM_NEWNEIGH or RTM_DELNEIGH
|
||||
req.ndm.ndm_family = AF_INET;
|
||||
req.ndm.ndm_state = NUD_PERMANENT;
|
||||
req.ndm.ndm_ifindex = ifindex;
|
||||
req.ndm.ndm_type = RTN_UNICAST;
|
||||
|
||||
addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4);
|
||||
addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen);
|
||||
|
||||
return netlink_talk (&req.n, &netlink_cmd);
|
||||
}
|
||||
|
||||
/* Routing table change via netlink interface. */
|
||||
/* Update flag indicates whether this is a "replace" or not. */
|
||||
static int
|
||||
@ -1874,7 +1946,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
||||
_netlink_route_debug(cmd, p, nexthop,
|
||||
routedesc, family);
|
||||
_netlink_route_build_multipath(routedesc, bytelen,
|
||||
nexthop, rta, rtnh, &src1);
|
||||
nexthop, rta, rtnh, &req.r, &src1);
|
||||
rtnh = RTNH_NEXT (rtnh);
|
||||
|
||||
if (cmd == RTM_NEWROUTE)
|
||||
|
@ -41,6 +41,9 @@ nl_msg_type_to_str (uint16_t msg_type);
|
||||
extern const char *
|
||||
nl_rtproto_to_str (u_char rtproto);
|
||||
|
||||
int
|
||||
netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen);
|
||||
|
||||
extern int netlink_route_read(void);
|
||||
extern int interface_lookup_netlink(void);
|
||||
|
||||
|
@ -3962,8 +3962,14 @@ rib_close_table (struct route_table *table)
|
||||
void
|
||||
rib_close (void)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct interface *ifp;
|
||||
|
||||
rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
|
||||
rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
|
||||
|
||||
for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
|
||||
}
|
||||
|
||||
/* Routing information base initialize. */
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "zebra/debug.h"
|
||||
#include "zebra/ipforward.h"
|
||||
#include "zebra/zebra_rnh.h"
|
||||
#include "zebra/rt_netlink.h"
|
||||
|
||||
/* Event list of zebra. */
|
||||
enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
|
||||
@ -415,6 +416,8 @@ nbr_connected_replacement_add_ipv6 (struct interface *ifp, struct in6_addr *addr
|
||||
prefix_copy(ifc->address, &p);
|
||||
|
||||
zebra_interface_nbr_address_add_update (ifp, ifc);
|
||||
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 1);
|
||||
}
|
||||
|
||||
void
|
||||
@ -436,6 +439,8 @@ nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
|
||||
|
||||
zebra_interface_nbr_address_delete_update (ifp, ifc);
|
||||
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 0);
|
||||
|
||||
nbr_connected_free (ifc);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user