mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-17 20:09:38 +00:00
This commit is contained in:
parent
8a92a8a00c
commit
5c610fafc4
@ -41,6 +41,7 @@
|
|||||||
#include "zebra/debug.h"
|
#include "zebra/debug.h"
|
||||||
#include "zebra/irdp.h"
|
#include "zebra/irdp.h"
|
||||||
#include "zebra/zebra_ptm.h"
|
#include "zebra/zebra_ptm.h"
|
||||||
|
#include "zebra/rt_netlink.h"
|
||||||
|
|
||||||
#define ZEBRA_PTM_SUPPORT
|
#define ZEBRA_PTM_SUPPORT
|
||||||
|
|
||||||
@ -528,6 +529,64 @@ if_delete_update (struct interface *ifp)
|
|||||||
ifp->ifindex = IFINDEX_INTERNAL;
|
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. */
|
/* Interface is up. */
|
||||||
void
|
void
|
||||||
if_up (struct interface *ifp)
|
if_up (struct interface *ifp)
|
||||||
@ -545,6 +604,7 @@ if_up (struct interface *ifp)
|
|||||||
}
|
}
|
||||||
zebra_interface_up_update (ifp);
|
zebra_interface_up_update (ifp);
|
||||||
|
|
||||||
|
if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (ifp);
|
||||||
|
|
||||||
/* Install connected routes to the kernel. */
|
/* Install connected routes to the kernel. */
|
||||||
if (ifp->connected)
|
if (ifp->connected)
|
||||||
@ -597,6 +657,8 @@ if_down (struct interface *ifp)
|
|||||||
|
|
||||||
/* Examine all static routes which direct to the interface. */
|
/* Examine all static routes which direct to the interface. */
|
||||||
rib_update ();
|
rib_update ();
|
||||||
|
|
||||||
|
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -213,6 +213,9 @@ struct zebra_if
|
|||||||
#endif /* SUNOS_5 */
|
#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_delete_update (struct interface *ifp);
|
||||||
extern void if_add_update (struct interface *ifp);
|
extern void if_add_update (struct interface *ifp);
|
||||||
extern void if_up (struct interface *);
|
extern void if_up (struct interface *);
|
||||||
|
@ -48,6 +48,11 @@ int kernel_address_delete_ipv4 (struct interface *a, struct connected *b)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void kernel_init (void) { return; }
|
void kernel_init (void) { return; }
|
||||||
#ifdef HAVE_SYS_WEAK_ALIAS_PRAGMA
|
#ifdef HAVE_SYS_WEAK_ALIAS_PRAGMA
|
||||||
#pragma weak route_read = kernel_init
|
#pragma weak route_read = kernel_init
|
||||||
|
@ -1483,8 +1483,30 @@ _netlink_route_build_singlepath(
|
|||||||
size_t req_size,
|
size_t req_size,
|
||||||
int cmd)
|
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))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
|
||||||
rtmsg->rtm_flags |= RTNH_F_ONLINK;
|
rtmsg->rtm_flags |= RTNH_F_ONLINK;
|
||||||
|
|
||||||
if (nexthop->type == NEXTHOP_TYPE_IPV4
|
if (nexthop->type == NEXTHOP_TYPE_IPV4
|
||||||
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
|
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
|
||||||
{
|
{
|
||||||
@ -1573,14 +1595,38 @@ _netlink_route_build_multipath(
|
|||||||
struct nexthop *nexthop,
|
struct nexthop *nexthop,
|
||||||
struct rtattr *rta,
|
struct rtattr *rta,
|
||||||
struct rtnexthop *rtnh,
|
struct rtnexthop *rtnh,
|
||||||
union g_addr **src
|
struct rtmsg *rtmsg,
|
||||||
)
|
union g_addr **src)
|
||||||
{
|
{
|
||||||
rtnh->rtnh_len = sizeof (*rtnh);
|
rtnh->rtnh_len = sizeof (*rtnh);
|
||||||
rtnh->rtnh_flags = 0;
|
rtnh->rtnh_flags = 0;
|
||||||
rtnh->rtnh_hops = 0;
|
rtnh->rtnh_hops = 0;
|
||||||
rta->rta_len += rtnh->rtnh_len;
|
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))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
|
||||||
rtnh->rtnh_flags |= RTNH_F_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. */
|
/* Routing table change via netlink interface. */
|
||||||
/* Update flag indicates whether this is a "replace" or not. */
|
/* Update flag indicates whether this is a "replace" or not. */
|
||||||
static int
|
static int
|
||||||
@ -1874,7 +1946,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
|||||||
_netlink_route_debug(cmd, p, nexthop,
|
_netlink_route_debug(cmd, p, nexthop,
|
||||||
routedesc, family);
|
routedesc, family);
|
||||||
_netlink_route_build_multipath(routedesc, bytelen,
|
_netlink_route_build_multipath(routedesc, bytelen,
|
||||||
nexthop, rta, rtnh, &src1);
|
nexthop, rta, rtnh, &req.r, &src1);
|
||||||
rtnh = RTNH_NEXT (rtnh);
|
rtnh = RTNH_NEXT (rtnh);
|
||||||
|
|
||||||
if (cmd == RTM_NEWROUTE)
|
if (cmd == RTM_NEWROUTE)
|
||||||
|
@ -41,6 +41,9 @@ nl_msg_type_to_str (uint16_t msg_type);
|
|||||||
extern const char *
|
extern const char *
|
||||||
nl_rtproto_to_str (u_char rtproto);
|
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 netlink_route_read(void);
|
||||||
extern int interface_lookup_netlink(void);
|
extern int interface_lookup_netlink(void);
|
||||||
|
|
||||||
|
@ -3962,8 +3962,14 @@ rib_close_table (struct route_table *table)
|
|||||||
void
|
void
|
||||||
rib_close (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_IP, SAFI_UNICAST, 0));
|
||||||
rib_close_table (vrf_table (AFI_IP6, 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. */
|
/* Routing information base initialize. */
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "zebra/debug.h"
|
#include "zebra/debug.h"
|
||||||
#include "zebra/ipforward.h"
|
#include "zebra/ipforward.h"
|
||||||
#include "zebra/zebra_rnh.h"
|
#include "zebra/zebra_rnh.h"
|
||||||
|
#include "zebra/rt_netlink.h"
|
||||||
|
|
||||||
/* Event list of zebra. */
|
/* Event list of zebra. */
|
||||||
enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
|
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);
|
prefix_copy(ifc->address, &p);
|
||||||
|
|
||||||
zebra_interface_nbr_address_add_update (ifp, ifc);
|
zebra_interface_nbr_address_add_update (ifp, ifc);
|
||||||
|
|
||||||
|
if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -436,6 +439,8 @@ nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
|
|||||||
|
|
||||||
zebra_interface_nbr_address_delete_update (ifp, ifc);
|
zebra_interface_nbr_address_delete_update (ifp, ifc);
|
||||||
|
|
||||||
|
if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 0);
|
||||||
|
|
||||||
nbr_connected_free (ifc);
|
nbr_connected_free (ifc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user