Merge branch 'pr/2986'

Conflicts:
	bgpd/bgp_network.c (BGP_ERR_* -> EC_BGP_*)

Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
David Lamparter 2018-09-18 12:46:42 +02:00
commit 2564f080da
5 changed files with 53 additions and 19 deletions

View File

@ -1705,8 +1705,14 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
stream_getl(s); /* RD low */ stream_getl(s); /* RD low */
} }
stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN); stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
if (!peer->nexthop.ifp) {
zlog_warn("%s: interface not set appropriately to handle some attributes",
peer->host);
return BGP_ATTR_PARSE_WITHDRAW;
}
attr->nh_ifindex = peer->nexthop.ifp->ifindex; attr->nh_ifindex = peer->nexthop.ifp->ifindex;
}
break; break;
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL: case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
case BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL: case BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL:
@ -1716,8 +1722,14 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
stream_getl(s); /* RD low */ stream_getl(s); /* RD low */
} }
stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN); stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
if (!peer->nexthop.ifp) {
zlog_warn("%s: interface not set appropriately to handle some attributes",
peer->host);
return BGP_ATTR_PARSE_WITHDRAW;
}
attr->nh_ifindex = peer->nexthop.ifp->ifindex; attr->nh_ifindex = peer->nexthop.ifp->ifindex;
}
if (attr->mp_nexthop_len if (attr->mp_nexthop_len
== BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) { == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
stream_getl(s); /* RD high */ stream_getl(s); /* RD high */
@ -1741,6 +1753,11 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
attr->mp_nexthop_len = IPV6_MAX_BYTELEN; attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
} }
if (!peer->nexthop.ifp) {
zlog_warn("%s: Interface not set appropriately to handle this some attributes",
peer->host);
return BGP_ATTR_PARSE_WITHDRAW;
}
attr->nh_lla_ifindex = peer->nexthop.ifp->ifindex; attr->nh_lla_ifindex = peer->nexthop.ifp->ifindex;
break; break;
default: default:

View File

@ -36,6 +36,7 @@
#include "filter.h" #include "filter.h"
#include "ns.h" #include "ns.h"
#include "lib_errors.h" #include "lib_errors.h"
#include "nexthop.h"
#include "bgpd/bgpd.h" #include "bgpd/bgpd.h"
#include "bgpd/bgp_open.h" #include "bgpd/bgp_open.h"
@ -44,6 +45,7 @@
#include "bgpd/bgp_debug.h" #include "bgpd/bgp_debug.h"
#include "bgpd/bgp_errors.h" #include "bgpd/bgp_errors.h"
#include "bgpd/bgp_network.h" #include "bgpd/bgp_network.h"
#include "bgpd/bgp_zebra.h"
extern struct zebra_privs_t bgpd_privs; extern struct zebra_privs_t bgpd_privs;
@ -618,15 +620,12 @@ int bgp_getsockname(struct peer *peer)
if (!peer->su_remote) if (!peer->su_remote)
return -1; return -1;
if (bgp_nexthop_set(peer->su_local, peer->su_remote, &peer->nexthop, if (!bgp_zebra_nexthop_set(peer->su_local, peer->su_remote,
peer)) { &peer->nexthop, peer)) {
#if defined(HAVE_CUMULUS) flog_err(EC_BGP_NH_UPD,
flog_err( "%s: nexthop_set failed, resetting connection - intf %p",
EC_BGP_NH_UPD, peer->host, peer->nexthop.ifp);
"%s: nexthop_set failed, resetting connection - intf %p",
peer->host, peer->nexthop.ifp);
return -1; return -1;
#endif
} }
return 0; return 0;
} }

View File

@ -777,8 +777,9 @@ static int if_get_ipv4_address(struct interface *ifp, struct in_addr *addr)
return 0; return 0;
} }
int bgp_nexthop_set(union sockunion *local, union sockunion *remote,
struct bgp_nexthop *nexthop, struct peer *peer) bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
struct bgp_nexthop *nexthop, struct peer *peer)
{ {
int ret = 0; int ret = 0;
struct interface *ifp = NULL; struct interface *ifp = NULL;
@ -786,9 +787,9 @@ int bgp_nexthop_set(union sockunion *local, union sockunion *remote,
memset(nexthop, 0, sizeof(struct bgp_nexthop)); memset(nexthop, 0, sizeof(struct bgp_nexthop));
if (!local) if (!local)
return -1; return false;
if (!remote) if (!remote)
return -1; return false;
if (local->sa.sa_family == AF_INET) { if (local->sa.sa_family == AF_INET) {
nexthop->v4 = local->sin.sin_addr; nexthop->v4 = local->sin.sin_addr;
@ -815,8 +816,24 @@ int bgp_nexthop_set(union sockunion *local, union sockunion *remote,
peer->bgp->vrf_id); peer->bgp->vrf_id);
} }
if (!ifp) if (!ifp) {
return -1; /*
* BGP views do not currently get proper data
* from zebra( when attached ) to be able to
* properly resolve nexthops, so give this
* instance type a pass.
*/
if (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
return true;
/*
* If we have no interface data but we have established
* some connection w/ zebra than something has gone
* terribly terribly wrong here, so say this failed
* If we do not any zebra connection then not
* having a ifp pointer is ok.
*/
return zclient_num_connects ? false : true;
}
nexthop->ifp = ifp; nexthop->ifp = ifp;
@ -912,7 +929,7 @@ int bgp_nexthop_set(union sockunion *local, union sockunion *remote,
/* If we have identified the local interface, there is no error for now. /* If we have identified the local interface, there is no error for now.
*/ */
return 0; return true;
} }
static struct in6_addr *bgp_info_to_ipv6_nexthop(struct bgp_info *info, static struct in6_addr *bgp_info_to_ipv6_nexthop(struct bgp_info *info,

View File

@ -73,6 +73,9 @@ extern int bgp_zebra_advertise_all_vni(struct bgp *, int);
extern int bgp_zebra_num_connects(void); extern int bgp_zebra_num_connects(void);
extern bool bgp_zebra_nexthop_set(union sockunion *, union sockunion *,
struct bgp_nexthop *, struct peer *);
struct bgp_pbr_action; struct bgp_pbr_action;
struct bgp_pbr_match; struct bgp_pbr_match;
struct bgp_pbr_match_entry; struct bgp_pbr_match_entry;

View File

@ -1470,8 +1470,6 @@ extern void bgp_terminate(void);
extern void bgp_reset(void); extern void bgp_reset(void);
extern time_t bgp_clock(void); extern time_t bgp_clock(void);
extern void bgp_zclient_reset(void); extern void bgp_zclient_reset(void);
extern int bgp_nexthop_set(union sockunion *, union sockunion *,
struct bgp_nexthop *, struct peer *);
extern struct bgp *bgp_get_default(void); extern struct bgp *bgp_get_default(void);
extern struct bgp *bgp_lookup(as_t, const char *); extern struct bgp *bgp_lookup(as_t, const char *);
extern struct bgp *bgp_lookup_by_name(const char *); extern struct bgp *bgp_lookup_by_name(const char *);