mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-15 16:32:01 +00:00
Zebra: Add IPv6 protocol filtering support & Setting Src of IPv6 routes
Ticket: Reviewed By: CCR-3335 Testing Done: bgpsmoke, ENHE tests etc. Add support for filtering routes from upper layer protocols to zebra via route-maps for IPv6. The same functionality already existed for IPv4. In addition, add support for setting source of routes via IPv6 protocol map. Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com> Reviewed-by: Vipin Kumar <vipin@cumulusnetworks.com>
This commit is contained in:
parent
3a8c7ba1ec
commit
0aabccc0a8
27
lib/if.c
27
lib/if.c
@ -257,7 +257,7 @@ if_lookup_by_name_len(const char *name, size_t namelen)
|
|||||||
|
|
||||||
/* Lookup interface by IPv4 address. */
|
/* Lookup interface by IPv4 address. */
|
||||||
struct interface *
|
struct interface *
|
||||||
if_lookup_exact_address (struct in_addr src)
|
if_lookup_exact_address (void *src, int family)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct listnode *cnode;
|
struct listnode *cnode;
|
||||||
@ -271,11 +271,19 @@ if_lookup_exact_address (struct in_addr src)
|
|||||||
{
|
{
|
||||||
p = c->address;
|
p = c->address;
|
||||||
|
|
||||||
if (p && p->family == AF_INET)
|
if (p && (p->family == family))
|
||||||
{
|
{
|
||||||
if (IPV4_ADDR_SAME (&p->u.prefix4, &src))
|
if (family == AF_INET)
|
||||||
|
{
|
||||||
|
if (IPV4_ADDR_SAME (&p->u.prefix4, (struct in_addr *)src))
|
||||||
return ifp;
|
return ifp;
|
||||||
}
|
}
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
{
|
||||||
|
if (IPV6_ADDR_SAME (&p->u.prefix4, (struct in6_addr *)src))
|
||||||
|
return ifp;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -283,7 +291,7 @@ if_lookup_exact_address (struct in_addr src)
|
|||||||
|
|
||||||
/* Lookup interface by IPv4 address. */
|
/* Lookup interface by IPv4 address. */
|
||||||
struct interface *
|
struct interface *
|
||||||
if_lookup_address (struct in_addr src)
|
if_lookup_address (void *matchaddr, int family)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct prefix addr;
|
struct prefix addr;
|
||||||
@ -293,9 +301,18 @@ if_lookup_address (struct in_addr src)
|
|||||||
struct connected *c;
|
struct connected *c;
|
||||||
struct interface *match;
|
struct interface *match;
|
||||||
|
|
||||||
|
if (family == AF_INET)
|
||||||
|
{
|
||||||
addr.family = AF_INET;
|
addr.family = AF_INET;
|
||||||
addr.u.prefix4 = src;
|
addr.u.prefix4 = *((struct in_addr *)matchaddr);
|
||||||
addr.prefixlen = IPV4_MAX_BITLEN;
|
addr.prefixlen = IPV4_MAX_BITLEN;
|
||||||
|
}
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
{
|
||||||
|
addr.family = AF_INET6;
|
||||||
|
addr.u.prefix6 = *((struct in6_addr *)matchaddr);
|
||||||
|
addr.prefixlen = IPV6_MAX_BITLEN;
|
||||||
|
}
|
||||||
|
|
||||||
match = NULL;
|
match = NULL;
|
||||||
|
|
||||||
|
4
lib/if.h
4
lib/if.h
@ -266,8 +266,8 @@ struct nbr_connected
|
|||||||
extern int if_cmp_func (struct interface *, struct interface *);
|
extern int if_cmp_func (struct interface *, struct interface *);
|
||||||
extern struct interface *if_create (const char *name, int namelen);
|
extern struct interface *if_create (const char *name, int namelen);
|
||||||
extern struct interface *if_lookup_by_index (unsigned int);
|
extern struct interface *if_lookup_by_index (unsigned int);
|
||||||
extern struct interface *if_lookup_exact_address (struct in_addr);
|
extern struct interface *if_lookup_exact_address (void *matchaddr, int family);
|
||||||
extern struct interface *if_lookup_address (struct in_addr);
|
extern struct interface *if_lookup_address (void *matchaddr, int family);
|
||||||
extern struct interface *if_lookup_prefix (struct prefix *prefix);
|
extern struct interface *if_lookup_prefix (struct prefix *prefix);
|
||||||
extern struct connected *if_anchor_lookup_by_address (struct in_addr src);
|
extern struct connected *if_anchor_lookup_by_address (struct in_addr src);
|
||||||
|
|
||||||
|
@ -2811,7 +2811,7 @@ ospf_read (struct thread *thread)
|
|||||||
/* Handle cases where the platform does not support retrieving the ifindex,
|
/* Handle cases where the platform does not support retrieving the ifindex,
|
||||||
and also platforms (such as Solaris 8) that claim to support ifindex
|
and also platforms (such as Solaris 8) that claim to support ifindex
|
||||||
retrieval but do not. */
|
retrieval but do not. */
|
||||||
ifp = if_lookup_address (iph->ip_src);
|
ifp = if_lookup_address ((void *)&iph->ip_src, AF_INET);
|
||||||
|
|
||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -255,7 +255,7 @@ rip2IfLookup (struct variable *v, oid name[], size_t *length,
|
|||||||
|
|
||||||
oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
|
oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
|
||||||
|
|
||||||
return if_lookup_exact_address (*addr);
|
return if_lookup_exact_address ((void *)addr, AF_INET);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1125,7 +1125,7 @@ rip_response_process (struct rip_packet *packet, int size,
|
|||||||
/* The datagram's IPv4 source address should be checked to see
|
/* The datagram's IPv4 source address should be checked to see
|
||||||
whether the datagram is from a valid neighbor; the source of the
|
whether the datagram is from a valid neighbor; the source of the
|
||||||
datagram must be on a directly connected network (RFC2453 - Sec. 3.9.2) */
|
datagram must be on a directly connected network (RFC2453 - Sec. 3.9.2) */
|
||||||
if (if_lookup_address(from->sin_addr) == NULL)
|
if (if_lookup_address((void *)&from->sin_addr, AF_INET) == NULL)
|
||||||
{
|
{
|
||||||
zlog_info ("This datagram doesn't came from a valid neighbor: %s",
|
zlog_info ("This datagram doesn't came from a valid neighbor: %s",
|
||||||
inet_ntoa (from->sin_addr));
|
inet_ntoa (from->sin_addr));
|
||||||
@ -1211,7 +1211,7 @@ rip_response_process (struct rip_packet *packet, int size,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! if_lookup_address (rte->nexthop))
|
if (! if_lookup_address ((void *)&rte->nexthop, AF_INET))
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct rip_info *rinfo;
|
struct rip_info *rinfo;
|
||||||
@ -1843,7 +1843,7 @@ rip_read (struct thread *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Which interface is this packet comes from. */
|
/* Which interface is this packet comes from. */
|
||||||
ifp = if_lookup_address (from.sin_addr);
|
ifp = if_lookup_address ((void *)&from.sin_addr, AF_INET);
|
||||||
|
|
||||||
/* RIP packet received */
|
/* RIP packet received */
|
||||||
if (IS_RIP_DEBUG_EVENT)
|
if (IS_RIP_DEBUG_EVENT)
|
||||||
@ -2525,7 +2525,7 @@ rip_update_process (int route_type)
|
|||||||
{
|
{
|
||||||
p = (struct prefix_ipv4 *) &rp->p;
|
p = (struct prefix_ipv4 *) &rp->p;
|
||||||
|
|
||||||
ifp = if_lookup_address (p->prefix);
|
ifp = if_lookup_address ((void *)&p->prefix, AF_INET);
|
||||||
if (! ifp)
|
if (! ifp)
|
||||||
{
|
{
|
||||||
zlog_warn ("Neighbor %s doesnt have connected interface!",
|
zlog_warn ("Neighbor %s doesnt have connected interface!",
|
||||||
|
@ -62,33 +62,6 @@ is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
zebra_check_addr (struct prefix *p)
|
|
||||||
{
|
|
||||||
if (p->family == AF_INET)
|
|
||||||
{
|
|
||||||
u_int32_t addr;
|
|
||||||
|
|
||||||
addr = p->u.prefix4.s_addr;
|
|
||||||
addr = ntohl (addr);
|
|
||||||
|
|
||||||
if (IPV4_NET127 (addr)
|
|
||||||
|| IN_CLASSD (addr)
|
|
||||||
|| IPV4_LINKLOCAL(addr))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
if (p->family == AF_INET6)
|
|
||||||
{
|
|
||||||
if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
|
|
||||||
return 0;
|
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_IPV6 */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
is_default (struct prefix *p)
|
is_default (struct prefix *p)
|
||||||
{
|
{
|
||||||
|
@ -46,8 +46,6 @@ extern void zebra_interface_address_add_update (struct interface *,
|
|||||||
struct connected *);
|
struct connected *);
|
||||||
extern void zebra_interface_address_delete_update (struct interface *,
|
extern void zebra_interface_address_delete_update (struct interface *,
|
||||||
struct connected *c);
|
struct connected *c);
|
||||||
extern int zebra_check_addr (struct prefix *);
|
|
||||||
|
|
||||||
extern int zebra_import_table (afi_t afi, u_int32_t table_id,
|
extern int zebra_import_table (afi_t afi, u_int32_t table_id,
|
||||||
u_int32_t metric, int add);
|
u_int32_t metric, int add);
|
||||||
|
|
||||||
|
@ -393,6 +393,7 @@ extern struct route_table *vrf_other_route_table (afi_t afi, u_int32_t table_id,
|
|||||||
u_int32_t vrf_id);
|
u_int32_t vrf_id);
|
||||||
extern int is_zebra_valid_kernel_table(u_int32_t table_id);
|
extern int is_zebra_valid_kernel_table(u_int32_t table_id);
|
||||||
extern int is_zebra_main_routing_table(u_int32_t table_id);
|
extern int is_zebra_main_routing_table(u_int32_t table_id);
|
||||||
|
extern int zebra_check_addr (struct prefix *p);
|
||||||
|
|
||||||
/* NOTE:
|
/* NOTE:
|
||||||
* All rib_add_ipv[46]* functions will not just add prefix into RIB, but
|
* All rib_add_ipv[46]* functions will not just add prefix into RIB, but
|
||||||
|
@ -1513,12 +1513,15 @@ _netlink_route_build_singlepath(
|
|||||||
addattr_l (nlmsg, req_size, RTA_GATEWAY,
|
addattr_l (nlmsg, req_size, RTA_GATEWAY,
|
||||||
&nexthop->gate.ipv4, bytelen);
|
&nexthop->gate.ipv4, bytelen);
|
||||||
|
|
||||||
if (nexthop->rmap_src.ipv4.s_addr && (cmd == RTM_NEWROUTE))
|
if (cmd == RTM_NEWROUTE)
|
||||||
|
{
|
||||||
|
if (nexthop->rmap_src.ipv4.s_addr)
|
||||||
addattr_l (nlmsg, req_size, RTA_PREFSRC,
|
addattr_l (nlmsg, req_size, RTA_PREFSRC,
|
||||||
&nexthop->rmap_src.ipv4, bytelen);
|
&nexthop->rmap_src.ipv4, bytelen);
|
||||||
else if (nexthop->src.ipv4.s_addr && (cmd == RTM_NEWROUTE))
|
else if (nexthop->src.ipv4.s_addr)
|
||||||
addattr_l (nlmsg, req_size, RTA_PREFSRC,
|
addattr_l (nlmsg, req_size, RTA_PREFSRC,
|
||||||
&nexthop->src.ipv4, bytelen);
|
&nexthop->src.ipv4, bytelen);
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug("netlink_route_multipath() (%s): "
|
zlog_debug("netlink_route_multipath() (%s): "
|
||||||
@ -1535,6 +1538,16 @@ _netlink_route_build_singlepath(
|
|||||||
addattr_l (nlmsg, req_size, RTA_GATEWAY,
|
addattr_l (nlmsg, req_size, RTA_GATEWAY,
|
||||||
&nexthop->gate.ipv6, bytelen);
|
&nexthop->gate.ipv6, bytelen);
|
||||||
|
|
||||||
|
if (cmd == RTM_NEWROUTE)
|
||||||
|
{
|
||||||
|
if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6))
|
||||||
|
addattr_l (nlmsg, req_size, RTA_PREFSRC,
|
||||||
|
&nexthop->rmap_src.ipv6, bytelen);
|
||||||
|
else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6))
|
||||||
|
addattr_l (nlmsg, req_size, RTA_PREFSRC,
|
||||||
|
&nexthop->src.ipv6, bytelen);
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug("netlink_route_multipath() (%s): "
|
zlog_debug("netlink_route_multipath() (%s): "
|
||||||
"nexthop via %s if %u",
|
"nexthop via %s if %u",
|
||||||
@ -1549,12 +1562,15 @@ _netlink_route_build_singlepath(
|
|||||||
{
|
{
|
||||||
addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);
|
addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);
|
||||||
|
|
||||||
if (nexthop->rmap_src.ipv4.s_addr && (cmd == RTM_NEWROUTE))
|
if (cmd == RTM_NEWROUTE)
|
||||||
|
{
|
||||||
|
if (nexthop->rmap_src.ipv4.s_addr)
|
||||||
addattr_l (nlmsg, req_size, RTA_PREFSRC,
|
addattr_l (nlmsg, req_size, RTA_PREFSRC,
|
||||||
&nexthop->rmap_src.ipv4, bytelen);
|
&nexthop->rmap_src.ipv4, bytelen);
|
||||||
else if (nexthop->src.ipv4.s_addr && (cmd == RTM_NEWROUTE))
|
else if (nexthop->src.ipv4.s_addr)
|
||||||
addattr_l (nlmsg, req_size, RTA_PREFSRC,
|
addattr_l (nlmsg, req_size, RTA_PREFSRC,
|
||||||
&nexthop->src.ipv4, bytelen);
|
&nexthop->src.ipv4, bytelen);
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug("netlink_route_multipath() (%s): "
|
zlog_debug("netlink_route_multipath() (%s): "
|
||||||
@ -1566,6 +1582,16 @@ _netlink_route_build_singlepath(
|
|||||||
{
|
{
|
||||||
addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);
|
addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);
|
||||||
|
|
||||||
|
if (cmd == RTM_NEWROUTE)
|
||||||
|
{
|
||||||
|
if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6))
|
||||||
|
addattr_l (nlmsg, req_size, RTA_PREFSRC,
|
||||||
|
&nexthop->rmap_src.ipv6, bytelen);
|
||||||
|
else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6))
|
||||||
|
addattr_l (nlmsg, req_size, RTA_PREFSRC,
|
||||||
|
&nexthop->src.ipv6, bytelen);
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug("netlink_route_multipath() (%s): "
|
zlog_debug("netlink_route_multipath() (%s): "
|
||||||
"nexthop via if %u", routedesc, nexthop->ifindex);
|
"nexthop via if %u", routedesc, nexthop->ifindex);
|
||||||
@ -1657,6 +1683,12 @@ _netlink_route_build_multipath(
|
|||||||
rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_GATEWAY,
|
rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_GATEWAY,
|
||||||
&nexthop->gate.ipv6, bytelen);
|
&nexthop->gate.ipv6, bytelen);
|
||||||
rtnh->rtnh_len += sizeof (struct rtattr) + bytelen;
|
rtnh->rtnh_len += sizeof (struct rtattr) + bytelen;
|
||||||
|
|
||||||
|
if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6))
|
||||||
|
*src = &nexthop->rmap_src;
|
||||||
|
else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6))
|
||||||
|
*src = &nexthop->src;
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug("netlink_route_multipath() (%s): "
|
zlog_debug("netlink_route_multipath() (%s): "
|
||||||
"nexthop via %s if %u",
|
"nexthop via %s if %u",
|
||||||
@ -1860,8 +1892,9 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
|||||||
{
|
{
|
||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
{
|
{
|
||||||
/* This only works for IPv4 now */
|
|
||||||
if (!setsrc)
|
if (!setsrc)
|
||||||
|
{
|
||||||
|
if (family == AF_INET)
|
||||||
{
|
{
|
||||||
if (nexthop->rmap_src.ipv4.s_addr != 0)
|
if (nexthop->rmap_src.ipv4.s_addr != 0)
|
||||||
{
|
{
|
||||||
@ -1874,6 +1907,20 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
|||||||
setsrc = 1;
|
setsrc = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
{
|
||||||
|
if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6))
|
||||||
|
{
|
||||||
|
src.ipv6 = nexthop->rmap_src.ipv6;
|
||||||
|
setsrc = 1;
|
||||||
|
}
|
||||||
|
else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6))
|
||||||
|
{
|
||||||
|
src.ipv6 = nexthop->src.ipv6;
|
||||||
|
setsrc = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1897,7 +1944,12 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (setsrc && (cmd == RTM_NEWROUTE))
|
if (setsrc && (cmd == RTM_NEWROUTE))
|
||||||
|
{
|
||||||
|
if (family == AF_INET)
|
||||||
addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv4, bytelen);
|
addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv4, bytelen);
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv6, bytelen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1920,6 +1972,8 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
|||||||
{
|
{
|
||||||
/* This only works for IPv4 now */
|
/* This only works for IPv4 now */
|
||||||
if (!setsrc)
|
if (!setsrc)
|
||||||
|
{
|
||||||
|
if (family == AF_INET)
|
||||||
{
|
{
|
||||||
if (nexthop->rmap_src.ipv4.s_addr != 0)
|
if (nexthop->rmap_src.ipv4.s_addr != 0)
|
||||||
{
|
{
|
||||||
@ -1932,6 +1986,20 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
|||||||
setsrc = 1;
|
setsrc = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
{
|
||||||
|
if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6))
|
||||||
|
{
|
||||||
|
src.ipv6 = nexthop->rmap_src.ipv6;
|
||||||
|
setsrc = 1;
|
||||||
|
}
|
||||||
|
else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6))
|
||||||
|
{
|
||||||
|
src.ipv6 = nexthop->src.ipv6;
|
||||||
|
setsrc = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1954,13 +2022,23 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
|||||||
|
|
||||||
if (!setsrc && src1)
|
if (!setsrc && src1)
|
||||||
{
|
{
|
||||||
|
if (family == AF_INET)
|
||||||
src.ipv4 = src1->ipv4;
|
src.ipv4 = src1->ipv4;
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
src.ipv6 = src1->ipv6;
|
||||||
|
|
||||||
setsrc = 1;
|
setsrc = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (setsrc && (cmd == RTM_NEWROUTE))
|
if (setsrc && (cmd == RTM_NEWROUTE))
|
||||||
|
{
|
||||||
|
if (family == AF_INET)
|
||||||
addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv4, bytelen);
|
addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv4, bytelen);
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv6, bytelen);
|
||||||
|
zlog_debug("Setting source");
|
||||||
|
}
|
||||||
|
|
||||||
if (rta->rta_len > RTA_LENGTH (0))
|
if (rta->rta_len > RTA_LENGTH (0))
|
||||||
addattr_l (&req.n, NL_PKT_BUF_SIZE, RTA_MULTIPATH, RTA_DATA (rta),
|
addattr_l (&req.n, NL_PKT_BUF_SIZE, RTA_MULTIPATH, RTA_DATA (rta),
|
||||||
|
@ -231,6 +231,33 @@ is_zebra_main_routing_table(u_int32_t table_id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zebra_check_addr (struct prefix *p)
|
||||||
|
{
|
||||||
|
if (p->family == AF_INET)
|
||||||
|
{
|
||||||
|
u_int32_t addr;
|
||||||
|
|
||||||
|
addr = p->u.prefix4.s_addr;
|
||||||
|
addr = ntohl (addr);
|
||||||
|
|
||||||
|
if (IPV4_NET127 (addr)
|
||||||
|
|| IN_CLASSD (addr)
|
||||||
|
|| IPV4_LINKLOCAL(addr))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
if (p->family == AF_INET6)
|
||||||
|
{
|
||||||
|
if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
|
||||||
|
return 0;
|
||||||
|
if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_IPV6 */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add nexthop to the end of a nexthop list. */
|
/* Add nexthop to the end of a nexthop list. */
|
||||||
static void
|
static void
|
||||||
_nexthop_add (struct nexthop **target, struct nexthop *nexthop)
|
_nexthop_add (struct nexthop **target, struct nexthop *nexthop)
|
||||||
@ -1298,7 +1325,6 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
|
|||||||
}
|
}
|
||||||
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1336,7 +1362,10 @@ nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
|
|||||||
prev_index != nexthop->ifindex ||
|
prev_index != nexthop->ifindex ||
|
||||||
((nexthop->type >= NEXTHOP_TYPE_IFINDEX &&
|
((nexthop->type >= NEXTHOP_TYPE_IFINDEX &&
|
||||||
nexthop->type < NEXTHOP_TYPE_IPV6) &&
|
nexthop->type < NEXTHOP_TYPE_IPV6) &&
|
||||||
prev_src.ipv4.s_addr != nexthop->rmap_src.ipv4.s_addr))
|
prev_src.ipv4.s_addr != nexthop->rmap_src.ipv4.s_addr) ||
|
||||||
|
((nexthop->type >= NEXTHOP_TYPE_IPV6 &&
|
||||||
|
nexthop->type < NEXTHOP_TYPE_BLACKHOLE) &&
|
||||||
|
!(IPV6_ADDR_SAME (&prev_src.ipv6, &nexthop->rmap_src.ipv6))))
|
||||||
{
|
{
|
||||||
SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
|
SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
|
||||||
SET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
|
SET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
|
||||||
|
@ -648,21 +648,46 @@ DEFUN (no_match_source_protocol,
|
|||||||
|
|
||||||
DEFUN (set_src,
|
DEFUN (set_src,
|
||||||
set_src_cmd,
|
set_src_cmd,
|
||||||
"set src A.B.C.D",
|
"set src (A.B.C.D|X:X::X:X)",
|
||||||
SET_STR
|
SET_STR
|
||||||
"src address for route\n"
|
"src address for route\n"
|
||||||
"src address\n")
|
"src address\n")
|
||||||
{
|
{
|
||||||
struct in_addr src;
|
union g_addr src;
|
||||||
struct interface *pif;
|
struct interface *pif = NULL;
|
||||||
|
int family;
|
||||||
|
struct prefix p;
|
||||||
|
|
||||||
if (inet_pton(AF_INET, argv[0], &src) <= 0)
|
if (inet_pton(AF_INET, argv[0], &src.ipv4) != 1)
|
||||||
{
|
{
|
||||||
vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
|
if (inet_pton(AF_INET6, argv[0], &src.ipv6) != 1)
|
||||||
|
{
|
||||||
|
vty_out (vty, "%% not a valid IPv4/v6 address%s", VTY_NEWLINE);
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
pif = if_lookup_exact_address (src);
|
p.family = family = AF_INET6;
|
||||||
|
p.u.prefix6 = src.ipv6;
|
||||||
|
p.prefixlen = IPV6_MAX_BITLEN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p.family = family = AF_INET;
|
||||||
|
p.u.prefix4 = src.ipv4;
|
||||||
|
p.prefixlen = IPV4_MAX_BITLEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!zebra_check_addr(&p))
|
||||||
|
{
|
||||||
|
vty_out (vty, "%% not a valid source IPv4/v6 address%s", VTY_NEWLINE);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (family == AF_INET)
|
||||||
|
pif = if_lookup_exact_address ((void *)&src.ipv4, AF_INET);
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
pif = if_lookup_exact_address ((void *)&src.ipv6, AF_INET6);
|
||||||
|
|
||||||
if (!pif)
|
if (!pif)
|
||||||
{
|
{
|
||||||
vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
|
vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
|
||||||
@ -673,7 +698,7 @@ DEFUN (set_src,
|
|||||||
|
|
||||||
DEFUN (no_set_src,
|
DEFUN (no_set_src,
|
||||||
no_set_src_cmd,
|
no_set_src_cmd,
|
||||||
"no set src",
|
"no set src {A.B.C.D|X:X::X:X}",
|
||||||
NO_STR
|
NO_STR
|
||||||
SET_STR
|
SET_STR
|
||||||
"Source address for route\n")
|
"Source address for route\n")
|
||||||
@ -684,14 +709,6 @@ DEFUN (no_set_src,
|
|||||||
return zebra_route_set_delete (vty, vty->index, "src", argv[0]);
|
return zebra_route_set_delete (vty, vty->index, "src", argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALIAS (no_set_src,
|
|
||||||
no_set_src_val_cmd,
|
|
||||||
"no set src (A.B.C.D)",
|
|
||||||
NO_STR
|
|
||||||
SET_STR
|
|
||||||
"src address for route\n"
|
|
||||||
"src address\n")
|
|
||||||
|
|
||||||
DEFUN (zebra_route_map_timer,
|
DEFUN (zebra_route_map_timer,
|
||||||
zebra_route_map_timer_cmd,
|
zebra_route_map_timer_cmd,
|
||||||
"zebra route-map delay-timer <0-600>",
|
"zebra route-map delay-timer <0-600>",
|
||||||
@ -822,6 +839,112 @@ DEFUN (show_ip_protocol,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN (ipv6_protocol,
|
||||||
|
ipv6_protocol_cmd,
|
||||||
|
"ipv6 protocol " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
|
||||||
|
IP6_STR
|
||||||
|
"Filter IPv6 routing info exchanged between zebra and protocol\n"
|
||||||
|
QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
|
||||||
|
"Route map name\n")
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u_int32_t table_id;
|
||||||
|
|
||||||
|
if (strcasecmp(argv[0], "any") == 0)
|
||||||
|
i = ZEBRA_ROUTE_MAX;
|
||||||
|
else
|
||||||
|
i = proto_name2num(argv[0]);
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
|
||||||
|
VTY_NEWLINE);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
if (proto_rm[AFI_IP6][i])
|
||||||
|
{
|
||||||
|
if (strcmp(proto_rm[AFI_IP6][i], argv[1]) == 0)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
|
XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP6][i]);
|
||||||
|
}
|
||||||
|
proto_rm[AFI_IP6][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
|
||||||
|
rib_update();
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (no_ipv6_protocol,
|
||||||
|
no_ipv6_protocol_cmd,
|
||||||
|
"no ipv6 protocol " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA,
|
||||||
|
NO_STR
|
||||||
|
IP6_STR
|
||||||
|
"Stop filtering IPv6 routing info between zebra and protocol\n"
|
||||||
|
QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
|
||||||
|
"Protocol from which to stop filtering routes\n")
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u_int32_t table_id;
|
||||||
|
|
||||||
|
if (strcasecmp(argv[0], "any") == 0)
|
||||||
|
i = ZEBRA_ROUTE_MAX;
|
||||||
|
else
|
||||||
|
i = proto_name2num(argv[0]);
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
|
||||||
|
VTY_NEWLINE);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
if (!proto_rm[AFI_IP6][i])
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
|
if ((argc == 2 && strcmp(argv[1], proto_rm[AFI_IP6][i]) == 0) ||
|
||||||
|
(argc < 2))
|
||||||
|
{
|
||||||
|
XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP6][i]);
|
||||||
|
proto_rm[AFI_IP6][i] = NULL;
|
||||||
|
rib_update();
|
||||||
|
}
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIAS (no_ipv6_protocol,
|
||||||
|
no_ipv6_protocol_val_cmd,
|
||||||
|
"no ipv6 protocol " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
|
||||||
|
NO_STR
|
||||||
|
IP6_STR
|
||||||
|
"Stop filtering IPv6 routing info between zebra and protocol\n"
|
||||||
|
QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
|
||||||
|
"route map name")
|
||||||
|
|
||||||
|
DEFUN (show_ipv6_protocol,
|
||||||
|
show_ipv6_protocol_cmd,
|
||||||
|
"show ipv6 protocol",
|
||||||
|
SHOW_STR
|
||||||
|
IP6_STR
|
||||||
|
"IPv6 protocol filtering status\n")
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
vty_out(vty, "Protocol : route-map %s", VTY_NEWLINE);
|
||||||
|
vty_out(vty, "------------------------%s", VTY_NEWLINE);
|
||||||
|
for (i=0;i<ZEBRA_ROUTE_MAX;i++)
|
||||||
|
{
|
||||||
|
if (proto_rm[AFI_IP6][i])
|
||||||
|
vty_out (vty, "%-10s : %-10s%s", zebra_route_string(i),
|
||||||
|
proto_rm[AFI_IP6][i],
|
||||||
|
VTY_NEWLINE);
|
||||||
|
else
|
||||||
|
vty_out (vty, "%-10s : none%s", zebra_route_string(i), VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
if (proto_rm[AFI_IP6][i])
|
||||||
|
vty_out (vty, "%-10s : %-10s%s", "any", proto_rm[AFI_IP6][i],
|
||||||
|
VTY_NEWLINE);
|
||||||
|
else
|
||||||
|
vty_out (vty, "%-10s : none%s", "any", VTY_NEWLINE);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (ip_protocol_nht_rmap,
|
DEFUN (ip_protocol_nht_rmap,
|
||||||
ip_protocol_nht_rmap_cmd,
|
ip_protocol_nht_rmap_cmd,
|
||||||
"ip nht " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
|
"ip nht " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
|
||||||
@ -1413,17 +1536,17 @@ route_set_src_compile (const char *arg)
|
|||||||
{
|
{
|
||||||
union g_addr src, *psrc;
|
union g_addr src, *psrc;
|
||||||
|
|
||||||
if (inet_pton(AF_INET, arg, &src.ipv4) != 1
|
if (
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
&& inet_pton(AF_INET6, arg, &src.ipv6) != 1
|
(inet_pton(AF_INET6, arg, &src.ipv6) == 1) ||
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
)
|
(src.ipv4.s_addr && (inet_pton(AF_INET, arg, &src.ipv4) == 1)))
|
||||||
return NULL;
|
{
|
||||||
|
|
||||||
psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr));
|
psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr));
|
||||||
*psrc = src;
|
*psrc = src;
|
||||||
|
|
||||||
return psrc;
|
return psrc;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free route map's compiled `set src' value. */
|
/* Free route map's compiled `set src' value. */
|
||||||
@ -1570,6 +1693,10 @@ zebra_routemap_config_write_protocol (struct vty *vty)
|
|||||||
vty_out (vty, "ip protocol %s route-map %s%s", zebra_route_string(i),
|
vty_out (vty, "ip protocol %s route-map %s%s", zebra_route_string(i),
|
||||||
proto_rm[AFI_IP][i], VTY_NEWLINE);
|
proto_rm[AFI_IP][i], VTY_NEWLINE);
|
||||||
|
|
||||||
|
if (proto_rm[AFI_IP6][i])
|
||||||
|
vty_out (vty, "ipv6 protocol %s route-map %s%s", zebra_route_string(i),
|
||||||
|
proto_rm[AFI_IP6][i], VTY_NEWLINE);
|
||||||
|
|
||||||
if (nht_rm[AFI_IP][i])
|
if (nht_rm[AFI_IP][i])
|
||||||
vty_out (vty, "ip nht %s route-map %s%s", zebra_route_string(i),
|
vty_out (vty, "ip nht %s route-map %s%s", zebra_route_string(i),
|
||||||
nht_rm[AFI_IP][i], VTY_NEWLINE);
|
nht_rm[AFI_IP][i], VTY_NEWLINE);
|
||||||
@ -1583,6 +1710,10 @@ zebra_routemap_config_write_protocol (struct vty *vty)
|
|||||||
vty_out (vty, "ip protocol %s route-map %s%s", "any",
|
vty_out (vty, "ip protocol %s route-map %s%s", "any",
|
||||||
proto_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
|
proto_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
|
||||||
|
|
||||||
|
if (proto_rm[AFI_IP6][ZEBRA_ROUTE_MAX])
|
||||||
|
vty_out (vty, "ipv6 protocol %s route-map %s%s", "any",
|
||||||
|
proto_rm[AFI_IP6][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
|
||||||
|
|
||||||
if (nht_rm[AFI_IP][ZEBRA_ROUTE_MAX])
|
if (nht_rm[AFI_IP][ZEBRA_ROUTE_MAX])
|
||||||
vty_out (vty, "ip nht %s route-map %s%s", "any",
|
vty_out (vty, "ip nht %s route-map %s%s", "any",
|
||||||
nht_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
|
nht_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
|
||||||
@ -1604,6 +1735,11 @@ zebra_route_map_init ()
|
|||||||
install_element (CONFIG_NODE, &no_ip_protocol_val_cmd);
|
install_element (CONFIG_NODE, &no_ip_protocol_val_cmd);
|
||||||
install_element (VIEW_NODE, &show_ip_protocol_cmd);
|
install_element (VIEW_NODE, &show_ip_protocol_cmd);
|
||||||
install_element (ENABLE_NODE, &show_ip_protocol_cmd);
|
install_element (ENABLE_NODE, &show_ip_protocol_cmd);
|
||||||
|
install_element (CONFIG_NODE, &ipv6_protocol_cmd);
|
||||||
|
install_element (CONFIG_NODE, &no_ipv6_protocol_cmd);
|
||||||
|
install_element (CONFIG_NODE, &no_ipv6_protocol_val_cmd);
|
||||||
|
install_element (VIEW_NODE, &show_ipv6_protocol_cmd);
|
||||||
|
install_element (ENABLE_NODE, &show_ipv6_protocol_cmd);
|
||||||
install_element (CONFIG_NODE, &ip_protocol_nht_rmap_cmd);
|
install_element (CONFIG_NODE, &ip_protocol_nht_rmap_cmd);
|
||||||
install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_cmd);
|
install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_cmd);
|
||||||
install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_val_cmd);
|
install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_val_cmd);
|
||||||
|
Loading…
Reference in New Issue
Block a user