forked from Mirror/frr
Merge pull request #8237 from pguibert6WIND/nhrp_use_zebra_2
Nhrp use zebra 2
This commit is contained in:
commit
3d4b999fab
16
include/linux/if_packet.h
Normal file
16
include/linux/if_packet.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef __LINUX_IF_PACKET_H
|
||||
#define __LINUX_IF_PACKET_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct sockaddr_ll {
|
||||
unsigned short sll_family;
|
||||
__be16 sll_protocol;
|
||||
int sll_ifindex;
|
||||
unsigned short sll_hatype;
|
||||
unsigned char sll_pkttype;
|
||||
unsigned char sll_halen;
|
||||
unsigned char sll_addr[8];
|
||||
};
|
||||
|
||||
#endif
|
71
include/linux/if_tunnel.h
Normal file
71
include/linux/if_tunnel.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
#ifndef _IF_TUNNEL_H_
|
||||
#define _IF_TUNNEL_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/in6.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
|
||||
#define SIOCGETTUNNEL (SIOCDEVPRIVATE + 0)
|
||||
#define SIOCADDTUNNEL (SIOCDEVPRIVATE + 1)
|
||||
#define SIOCDELTUNNEL (SIOCDEVPRIVATE + 2)
|
||||
#define SIOCCHGTUNNEL (SIOCDEVPRIVATE + 3)
|
||||
#define SIOCGETPRL (SIOCDEVPRIVATE + 4)
|
||||
#define SIOCADDPRL (SIOCDEVPRIVATE + 5)
|
||||
#define SIOCDELPRL (SIOCDEVPRIVATE + 6)
|
||||
#define SIOCCHGPRL (SIOCDEVPRIVATE + 7)
|
||||
|
||||
#define GRE_CSUM __cpu_to_be16(0x8000)
|
||||
#define GRE_ROUTING __cpu_to_be16(0x4000)
|
||||
#define GRE_KEY __cpu_to_be16(0x2000)
|
||||
#define GRE_SEQ __cpu_to_be16(0x1000)
|
||||
#define GRE_STRICT __cpu_to_be16(0x0800)
|
||||
#define GRE_REC __cpu_to_be16(0x0700)
|
||||
#define GRE_FLAGS __cpu_to_be16(0x00F8)
|
||||
#define GRE_VERSION __cpu_to_be16(0x0007)
|
||||
|
||||
struct ip_tunnel_parm {
|
||||
char name[IFNAMSIZ];
|
||||
int link;
|
||||
__be16 i_flags;
|
||||
__be16 o_flags;
|
||||
__be32 i_key;
|
||||
__be32 o_key;
|
||||
struct iphdr iph;
|
||||
};
|
||||
|
||||
/* SIT-mode i_flags */
|
||||
#define SIT_ISATAP 0x0001
|
||||
|
||||
struct ip_tunnel_prl {
|
||||
__be32 addr;
|
||||
__u16 flags;
|
||||
__u16 __reserved;
|
||||
__u32 datalen;
|
||||
__u32 __reserved2;
|
||||
/* data follows */
|
||||
};
|
||||
|
||||
/* PRL flags */
|
||||
#define PRL_DEFAULT 0x0001
|
||||
|
||||
enum {
|
||||
IFLA_GRE_UNSPEC,
|
||||
IFLA_GRE_LINK,
|
||||
IFLA_GRE_IFLAGS,
|
||||
IFLA_GRE_OFLAGS,
|
||||
IFLA_GRE_IKEY,
|
||||
IFLA_GRE_OKEY,
|
||||
IFLA_GRE_LOCAL,
|
||||
IFLA_GRE_REMOTE,
|
||||
IFLA_GRE_TTL,
|
||||
IFLA_GRE_TOS,
|
||||
IFLA_GRE_PMTUDISC,
|
||||
__IFLA_GRE_MAX,
|
||||
};
|
||||
|
||||
#define IFLA_GRE_MAX (__IFLA_GRE_MAX - 1)
|
||||
|
||||
#endif /* _IF_TUNNEL_H_ */
|
|
@ -461,7 +461,10 @@ static const struct zebra_desc_table command_types[] = {
|
|||
DESC_ENTRY(ZEBRA_NHRP_NEIGH_UNREGISTER),
|
||||
DESC_ENTRY(ZEBRA_NEIGH_IP_ADD),
|
||||
DESC_ENTRY(ZEBRA_NEIGH_IP_DEL),
|
||||
DESC_ENTRY(ZEBRA_CONFIGURE_ARP)};
|
||||
DESC_ENTRY(ZEBRA_CONFIGURE_ARP),
|
||||
DESC_ENTRY(ZEBRA_GRE_GET),
|
||||
DESC_ENTRY(ZEBRA_GRE_UPDATE),
|
||||
DESC_ENTRY(ZEBRA_GRE_SOURCE_SET)};
|
||||
#undef DESC_ENTRY
|
||||
|
||||
static const struct zebra_desc_table unknown = {0, "unknown", '?'};
|
||||
|
|
|
@ -3931,6 +3931,11 @@ static int zclient_read(struct thread *thread)
|
|||
(*zclient->neighbor_get)(command, zclient, length,
|
||||
vrf_id);
|
||||
break;
|
||||
case ZEBRA_GRE_UPDATE:
|
||||
if (zclient->gre_update)
|
||||
(*zclient->gre_update)(command, zclient,
|
||||
length, vrf_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -4252,3 +4257,23 @@ int zclient_neigh_ip_decode(struct stream *s, struct zapi_neigh_ip *api)
|
|||
stream_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int zclient_send_zebra_gre_request(struct zclient *client,
|
||||
struct interface *ifp)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
if (!client || client->sock < 0) {
|
||||
zlog_err("%s : zclient not ready", __func__);
|
||||
return -1;
|
||||
}
|
||||
s = client->obuf;
|
||||
stream_reset(s);
|
||||
zclient_create_header(s,
|
||||
ZEBRA_GRE_GET,
|
||||
ifp->vrf_id);
|
||||
stream_putl(s, ifp->ifindex);
|
||||
stream_putw_at(s, 0, stream_get_endp(s));
|
||||
zclient_send_message(client);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -232,6 +232,9 @@ typedef enum {
|
|||
ZEBRA_NEIGH_IP_ADD,
|
||||
ZEBRA_NEIGH_IP_DEL,
|
||||
ZEBRA_CONFIGURE_ARP,
|
||||
ZEBRA_GRE_GET,
|
||||
ZEBRA_GRE_UPDATE,
|
||||
ZEBRA_GRE_SOURCE_SET,
|
||||
} zebra_message_types_t;
|
||||
|
||||
enum zebra_error_types {
|
||||
|
@ -393,6 +396,7 @@ struct zclient {
|
|||
void (*neighbor_added)(ZAPI_CALLBACK_ARGS);
|
||||
void (*neighbor_removed)(ZAPI_CALLBACK_ARGS);
|
||||
void (*neighbor_get)(ZAPI_CALLBACK_ARGS);
|
||||
void (*gre_update)(ZAPI_CALLBACK_ARGS);
|
||||
};
|
||||
|
||||
/* Zebra API message flag. */
|
||||
|
@ -1228,6 +1232,8 @@ struct zapi_client_close_info {
|
|||
extern int zapi_client_close_notify_decode(struct stream *s,
|
||||
struct zapi_client_close_info *info);
|
||||
|
||||
extern int zclient_send_zebra_gre_request(struct zclient *client,
|
||||
struct interface *ifp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -7,30 +7,12 @@
|
|||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <asm/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/if_tunnel.h>
|
||||
#include <linux/limits.h>
|
||||
#include "zebra.h"
|
||||
#include <linux/if_packet.h>
|
||||
|
||||
#include "nhrp_protocol.h"
|
||||
#include "os.h"
|
||||
#include "netlink.h"
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy(char *__restrict dest,
|
||||
|
|
|
@ -7,21 +7,16 @@
|
|||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zebra.h>
|
||||
#include <vrf.h>
|
||||
#include <if.h>
|
||||
|
||||
union sockunion;
|
||||
struct interface;
|
||||
|
||||
extern int netlink_nflog_group;
|
||||
extern int netlink_mcast_nflog_group;
|
||||
extern int netlink_req_fd;
|
||||
|
||||
void netlink_init(void);
|
||||
int netlink_configure_arp(unsigned int ifindex, int pf);
|
||||
void netlink_update_binding(struct interface *ifp, union sockunion *proto,
|
||||
union sockunion *nbma);
|
||||
void netlink_set_nflog_group(int nlgroup);
|
||||
|
||||
void netlink_gre_get_info(unsigned int ifindex, uint32_t *gre_key,
|
||||
unsigned int *link_index, struct in_addr *saddr);
|
||||
void netlink_gre_set_link(unsigned int ifindex, unsigned int link_index);
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "netlink.h"
|
||||
#include "znl.h"
|
||||
|
||||
int netlink_req_fd = -1;
|
||||
int netlink_nflog_group;
|
||||
static int netlink_log_fd = -1;
|
||||
static struct thread *netlink_log_thread;
|
||||
|
@ -203,10 +202,3 @@ void nhrp_neighbor_operation(ZAPI_CALLBACK_ARGS)
|
|||
nhrp_cache_set_used(c, state == ZEBRA_NEIGH_STATE_REACHABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void netlink_init(void)
|
||||
{
|
||||
netlink_req_fd = znl_open(NETLINK_ROUTE, 0);
|
||||
if (netlink_req_fd < 0)
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
/* NHRP netlink/GRE tunnel configuration code
|
||||
* Copyright (c) 2014-2016 Timo Teräs
|
||||
*
|
||||
* This file is free software: you may copy, redistribute and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <linux/if_tunnel.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "netlink.h"
|
||||
#include "znl.h"
|
||||
|
||||
static int __netlink_gre_get_data(struct zbuf *zb, struct zbuf *data,
|
||||
int ifindex)
|
||||
{
|
||||
struct nlmsghdr *n;
|
||||
struct ifinfomsg *ifi;
|
||||
struct zbuf payload, rtapayload;
|
||||
struct rtattr *rta;
|
||||
|
||||
debugf(NHRP_DEBUG_KERNEL, "netlink-link-gre: get-info %u", ifindex);
|
||||
|
||||
n = znl_nlmsg_push(zb, RTM_GETLINK, NLM_F_REQUEST);
|
||||
ifi = znl_push(zb, sizeof(*ifi));
|
||||
*ifi = (struct ifinfomsg){
|
||||
.ifi_index = ifindex,
|
||||
};
|
||||
znl_nlmsg_complete(zb, n);
|
||||
|
||||
if (zbuf_send(zb, netlink_req_fd) < 0
|
||||
|| zbuf_recv(zb, netlink_req_fd) < 0)
|
||||
return -1;
|
||||
|
||||
n = znl_nlmsg_pull(zb, &payload);
|
||||
if (!n)
|
||||
return -1;
|
||||
|
||||
if (n->nlmsg_type != RTM_NEWLINK)
|
||||
return -1;
|
||||
|
||||
ifi = znl_pull(&payload, sizeof(struct ifinfomsg));
|
||||
if (!ifi)
|
||||
return -1;
|
||||
|
||||
debugf(NHRP_DEBUG_KERNEL,
|
||||
"netlink-link-gre: ifindex %u, receive msg_type %u, msg_flags %u",
|
||||
ifi->ifi_index, n->nlmsg_type, n->nlmsg_flags);
|
||||
|
||||
if (ifi->ifi_index != ifindex)
|
||||
return -1;
|
||||
|
||||
while ((rta = znl_rta_pull(&payload, &rtapayload)) != NULL)
|
||||
if (rta->rta_type == IFLA_LINKINFO)
|
||||
break;
|
||||
if (!rta)
|
||||
return -1;
|
||||
|
||||
payload = rtapayload;
|
||||
while ((rta = znl_rta_pull(&payload, &rtapayload)) != NULL)
|
||||
if (rta->rta_type == IFLA_INFO_DATA)
|
||||
break;
|
||||
if (!rta)
|
||||
return -1;
|
||||
|
||||
*data = rtapayload;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void netlink_gre_get_info(unsigned int ifindex, uint32_t *gre_key,
|
||||
unsigned int *link_index, struct in_addr *saddr)
|
||||
{
|
||||
struct zbuf *zb = zbuf_alloc(8192), data, rtapl;
|
||||
struct rtattr *rta;
|
||||
|
||||
*link_index = 0;
|
||||
*gre_key = 0;
|
||||
saddr->s_addr = 0;
|
||||
|
||||
if (__netlink_gre_get_data(zb, &data, ifindex) < 0)
|
||||
goto err;
|
||||
|
||||
while ((rta = znl_rta_pull(&data, &rtapl)) != NULL) {
|
||||
switch (rta->rta_type) {
|
||||
case IFLA_GRE_LINK:
|
||||
*link_index = zbuf_get32(&rtapl);
|
||||
break;
|
||||
case IFLA_GRE_IKEY:
|
||||
case IFLA_GRE_OKEY:
|
||||
*gre_key = zbuf_get32(&rtapl);
|
||||
break;
|
||||
case IFLA_GRE_LOCAL:
|
||||
saddr->s_addr = zbuf_get32(&rtapl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
err:
|
||||
zbuf_free(zb);
|
||||
}
|
||||
|
||||
void netlink_gre_set_link(unsigned int ifindex, unsigned int link_index)
|
||||
{
|
||||
struct nlmsghdr *n;
|
||||
struct ifinfomsg *ifi;
|
||||
struct rtattr *rta_info, *rta_data, *rta;
|
||||
struct zbuf *zr = zbuf_alloc(8192), data, rtapl;
|
||||
struct zbuf *zb = zbuf_alloc(8192);
|
||||
size_t len;
|
||||
|
||||
if (__netlink_gre_get_data(zr, &data, ifindex) < 0)
|
||||
goto err;
|
||||
|
||||
n = znl_nlmsg_push(zb, RTM_NEWLINK, NLM_F_REQUEST);
|
||||
ifi = znl_push(zb, sizeof(*ifi));
|
||||
*ifi = (struct ifinfomsg){
|
||||
.ifi_index = ifindex,
|
||||
};
|
||||
rta_info = znl_rta_nested_push(zb, IFLA_LINKINFO);
|
||||
znl_rta_push(zb, IFLA_INFO_KIND, "gre", 3);
|
||||
rta_data = znl_rta_nested_push(zb, IFLA_INFO_DATA);
|
||||
|
||||
znl_rta_push_u32(zb, IFLA_GRE_LINK, link_index);
|
||||
while ((rta = znl_rta_pull(&data, &rtapl)) != NULL) {
|
||||
if (rta->rta_type == IFLA_GRE_LINK)
|
||||
continue;
|
||||
len = zbuf_used(&rtapl);
|
||||
znl_rta_push(zb, rta->rta_type, zbuf_pulln(&rtapl, len), len);
|
||||
}
|
||||
|
||||
znl_rta_nested_complete(zb, rta_data);
|
||||
znl_rta_nested_complete(zb, rta_info);
|
||||
|
||||
znl_nlmsg_complete(zb, n);
|
||||
zbuf_send(zb, netlink_req_fd);
|
||||
zbuf_recv(zb, netlink_req_fd);
|
||||
err:
|
||||
zbuf_free(zb);
|
||||
zbuf_free(zr);
|
||||
}
|
|
@ -19,14 +19,52 @@
|
|||
|
||||
#include "nhrpd.h"
|
||||
#include "os.h"
|
||||
#include "netlink.h"
|
||||
#include "hash.h"
|
||||
|
||||
DEFINE_MTYPE_STATIC(NHRPD, NHRP_IF, "NHRP interface");
|
||||
DEFINE_MTYPE_STATIC(NHRPD, NHRP_IF_GRE, "NHRP GRE interface");
|
||||
|
||||
struct hash *nhrp_gre_list;
|
||||
|
||||
static void nhrp_interface_update_cache_config(struct interface *ifp,
|
||||
bool available,
|
||||
uint8_t family);
|
||||
|
||||
static unsigned int nhrp_gre_info_key(const void *data)
|
||||
{
|
||||
const struct nhrp_gre_info *r = data;
|
||||
|
||||
return r->ifindex;
|
||||
}
|
||||
|
||||
static bool nhrp_gre_info_cmp(const void *data, const void *key)
|
||||
{
|
||||
const struct nhrp_gre_info *a = data, *b = key;
|
||||
|
||||
if (a->ifindex == b->ifindex)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void *nhrp_interface_gre_alloc(void *data)
|
||||
{
|
||||
struct nhrp_gre_info *a;
|
||||
struct nhrp_gre_info *b = data;
|
||||
|
||||
a = XMALLOC(MTYPE_NHRP_IF_GRE, sizeof(struct nhrp_gre_info));
|
||||
memcpy(a, b, sizeof(struct nhrp_gre_info));
|
||||
return a;
|
||||
}
|
||||
|
||||
struct nhrp_gre_info *nhrp_gre_info_alloc(struct nhrp_gre_info *p)
|
||||
{
|
||||
struct nhrp_gre_info *a;
|
||||
|
||||
a = (struct nhrp_gre_info *)hash_get(nhrp_gre_list, p,
|
||||
nhrp_interface_gre_alloc);
|
||||
return a;
|
||||
}
|
||||
|
||||
static int nhrp_if_new_hook(struct interface *ifp)
|
||||
{
|
||||
struct nhrp_interface *nifp;
|
||||
|
@ -74,6 +112,9 @@ void nhrp_interface_init(void)
|
|||
{
|
||||
hook_register_prio(if_add, 0, nhrp_if_new_hook);
|
||||
hook_register_prio(if_del, 0, nhrp_if_delete_hook);
|
||||
|
||||
nhrp_gre_list = hash_create(nhrp_gre_info_key, nhrp_gre_info_cmp,
|
||||
"NHRP GRE list Hash");
|
||||
}
|
||||
|
||||
void nhrp_interface_update_mtu(struct interface *ifp, afi_t afi)
|
||||
|
@ -102,14 +143,16 @@ static void nhrp_interface_update_source(struct interface *ifp)
|
|||
{
|
||||
struct nhrp_interface *nifp = ifp->info;
|
||||
|
||||
if (!nifp->source || !nifp->nbmaifp
|
||||
|| (ifindex_t)nifp->linkidx == nifp->nbmaifp->ifindex)
|
||||
if (!nifp->source || !nifp->nbmaifp ||
|
||||
((ifindex_t)nifp->link_idx == nifp->nbmaifp->ifindex &&
|
||||
(nifp->link_vrf_id == nifp->nbmaifp->vrf_id)))
|
||||
return;
|
||||
|
||||
nifp->linkidx = nifp->nbmaifp->ifindex;
|
||||
debugf(NHRP_DEBUG_IF, "%s: bound device index changed to %d", ifp->name,
|
||||
nifp->linkidx);
|
||||
netlink_gre_set_link(ifp->ifindex, nifp->linkidx);
|
||||
nifp->link_idx = nifp->nbmaifp->ifindex;
|
||||
nifp->link_vrf_id = nifp->nbmaifp->vrf_id;
|
||||
debugf(NHRP_DEBUG_IF, "%s: bound device index changed to %d, vr %u",
|
||||
ifp->name, nifp->link_idx, nifp->link_vrf_id);
|
||||
nhrp_send_zebra_gre_source_set(ifp, nifp->link_idx, nifp->link_vrf_id);
|
||||
}
|
||||
|
||||
static void nhrp_interface_interface_notifier(struct notifier_block *n,
|
||||
|
@ -136,7 +179,8 @@ static void nhrp_interface_interface_notifier(struct notifier_block *n,
|
|||
}
|
||||
}
|
||||
|
||||
static void nhrp_interface_update_nbma(struct interface *ifp)
|
||||
void nhrp_interface_update_nbma(struct interface *ifp,
|
||||
struct nhrp_gre_info *gre_info)
|
||||
{
|
||||
struct nhrp_interface *nifp = ifp->info, *nbmanifp = NULL;
|
||||
struct interface *nbmaifp = NULL;
|
||||
|
@ -145,21 +189,32 @@ static void nhrp_interface_update_nbma(struct interface *ifp)
|
|||
sockunion_family(&nbma) = AF_UNSPEC;
|
||||
|
||||
if (nifp->source)
|
||||
nbmaifp = if_lookup_by_name(nifp->source, VRF_DEFAULT);
|
||||
nbmaifp = if_lookup_by_name(nifp->source, nifp->link_vrf_id);
|
||||
|
||||
switch (ifp->ll_type) {
|
||||
case ZEBRA_LLT_IPGRE: {
|
||||
struct in_addr saddr = {0};
|
||||
netlink_gre_get_info(ifp->ifindex, &nifp->grekey,
|
||||
&nifp->linkidx, &saddr);
|
||||
|
||||
if (!gre_info) {
|
||||
nhrp_send_zebra_gre_request(ifp);
|
||||
return;
|
||||
}
|
||||
nifp->i_grekey = gre_info->ikey;
|
||||
nifp->o_grekey = gre_info->okey;
|
||||
nifp->link_idx = gre_info->ifindex_link;
|
||||
nifp->link_vrf_id = gre_info->vrfid_link;
|
||||
saddr.s_addr = gre_info->vtep_ip.s_addr;
|
||||
|
||||
debugf(NHRP_DEBUG_IF, "%s: GRE: %x %x %x", ifp->name,
|
||||
nifp->grekey, nifp->linkidx, saddr.s_addr);
|
||||
if (saddr.s_addr != INADDR_ANY)
|
||||
sockunion_set(&nbma, AF_INET, (uint8_t *)&saddr.s_addr,
|
||||
nifp->i_grekey, nifp->link_idx, saddr.s_addr);
|
||||
if (saddr.s_addr)
|
||||
sockunion_set(&nbma, AF_INET,
|
||||
(uint8_t *)&saddr.s_addr,
|
||||
sizeof(saddr.s_addr));
|
||||
else if (!nbmaifp && nifp->linkidx != IFINDEX_INTERNAL)
|
||||
else if (!nbmaifp && nifp->link_idx != IFINDEX_INTERNAL)
|
||||
nbmaifp =
|
||||
if_lookup_by_index(nifp->linkidx, VRF_DEFAULT);
|
||||
if_lookup_by_index(nifp->link_idx,
|
||||
nifp->link_vrf_id);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
|
@ -322,7 +377,7 @@ int nhrp_ifp_create(struct interface *ifp)
|
|||
ifp->name, ifp->ifindex, ifp->ll_type,
|
||||
if_link_type_str(ifp->ll_type));
|
||||
|
||||
nhrp_interface_update_nbma(ifp);
|
||||
nhrp_interface_update_nbma(ifp, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -402,7 +457,7 @@ static void nhrp_interface_update_cache_config(struct interface *ifp, bool avail
|
|||
int nhrp_ifp_up(struct interface *ifp)
|
||||
{
|
||||
debugf(NHRP_DEBUG_IF, "if-up: %s", ifp->name);
|
||||
nhrp_interface_update_nbma(ifp);
|
||||
nhrp_interface_update_nbma(ifp, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -493,5 +548,5 @@ void nhrp_interface_set_source(struct interface *ifp, const char *ifname)
|
|||
free(nifp->source);
|
||||
nifp->source = ifname ? strdup(ifname) : NULL;
|
||||
|
||||
nhrp_interface_update_nbma(ifp);
|
||||
nhrp_interface_update_nbma(ifp, NULL);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "filter.h"
|
||||
|
||||
#include "nhrpd.h"
|
||||
#include "netlink.h"
|
||||
#include "nhrp_errors.h"
|
||||
|
||||
DEFINE_MGROUP(NHRPD, "NHRP");
|
||||
|
@ -154,7 +153,6 @@ int main(int argc, char **argv)
|
|||
assert(nhrpd_privs.change);
|
||||
nhrpd_privs.change(ZPRIVS_RAISE);
|
||||
|
||||
netlink_init();
|
||||
evmgr_init();
|
||||
nhrp_vc_init();
|
||||
nhrp_packet_init();
|
||||
|
|
|
@ -380,6 +380,7 @@ void nhrp_zebra_init(void)
|
|||
zclient->neighbor_added = nhrp_neighbor_operation;
|
||||
zclient->neighbor_removed = nhrp_neighbor_operation;
|
||||
zclient->neighbor_get = nhrp_neighbor_operation;
|
||||
zclient->gre_update = nhrp_gre_update;
|
||||
zclient_init(zclient, ZEBRA_ROUTE_NHRP, 0, &nhrpd_privs);
|
||||
}
|
||||
|
||||
|
@ -412,6 +413,33 @@ void nhrp_send_zebra_configure_arp(struct interface *ifp, int family)
|
|||
zclient_send_message(zclient);
|
||||
}
|
||||
|
||||
void nhrp_send_zebra_gre_source_set(struct interface *ifp,
|
||||
unsigned int link_idx,
|
||||
vrf_id_t link_vrf_id)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
if (!zclient || zclient->sock < 0) {
|
||||
zlog_err("%s : zclient not ready", __func__);
|
||||
return;
|
||||
}
|
||||
if (link_idx == IFINDEX_INTERNAL || link_vrf_id == VRF_UNKNOWN) {
|
||||
/* silently ignore */
|
||||
return;
|
||||
}
|
||||
s = zclient->obuf;
|
||||
stream_reset(s);
|
||||
zclient_create_header(s,
|
||||
ZEBRA_GRE_SOURCE_SET,
|
||||
ifp->vrf_id);
|
||||
stream_putl(s, ifp->ifindex);
|
||||
stream_putl(s, link_idx);
|
||||
stream_putl(s, link_vrf_id);
|
||||
stream_putl(s, 0); /* mtu provisioning */
|
||||
stream_putw_at(s, 0, stream_get_endp(s));
|
||||
zclient_send_message(zclient);
|
||||
}
|
||||
|
||||
void nhrp_send_zebra_nbr(union sockunion *in,
|
||||
union sockunion *out,
|
||||
struct interface *ifp)
|
||||
|
@ -429,6 +457,11 @@ void nhrp_send_zebra_nbr(union sockunion *in,
|
|||
zclient_send_message(zclient);
|
||||
}
|
||||
|
||||
int nhrp_send_zebra_gre_request(struct interface *ifp)
|
||||
{
|
||||
return zclient_send_zebra_gre_request(zclient, ifp);
|
||||
}
|
||||
|
||||
void nhrp_zebra_terminate(void)
|
||||
{
|
||||
nhrp_zebra_register_neigh(VRF_DEFAULT, AFI_IP, false);
|
||||
|
@ -441,3 +474,48 @@ void nhrp_zebra_terminate(void)
|
|||
route_table_finish(zebra_rib[AFI_IP]);
|
||||
route_table_finish(zebra_rib[AFI_IP6]);
|
||||
}
|
||||
|
||||
void nhrp_gre_update(ZAPI_CALLBACK_ARGS)
|
||||
{
|
||||
struct stream *s;
|
||||
struct nhrp_gre_info gre_info, *val;
|
||||
struct interface *ifp;
|
||||
|
||||
/* result */
|
||||
s = zclient->ibuf;
|
||||
if (vrf_id != VRF_DEFAULT)
|
||||
return;
|
||||
|
||||
/* read GRE information */
|
||||
STREAM_GETL(s, gre_info.ifindex);
|
||||
STREAM_GETL(s, gre_info.ikey);
|
||||
STREAM_GETL(s, gre_info.okey);
|
||||
STREAM_GETL(s, gre_info.ifindex_link);
|
||||
STREAM_GETL(s, gre_info.vrfid_link);
|
||||
STREAM_GETL(s, gre_info.vtep_ip.s_addr);
|
||||
STREAM_GETL(s, gre_info.vtep_ip_remote.s_addr);
|
||||
if (gre_info.ifindex == IFINDEX_INTERNAL)
|
||||
val = NULL;
|
||||
else
|
||||
val = hash_lookup(nhrp_gre_list, &gre_info);
|
||||
if (val) {
|
||||
if (gre_info.vtep_ip.s_addr != val->vtep_ip.s_addr ||
|
||||
gre_info.vrfid_link != val->vrfid_link ||
|
||||
gre_info.ifindex_link != val->ifindex_link ||
|
||||
gre_info.ikey != val->ikey ||
|
||||
gre_info.okey != val->okey) {
|
||||
/* update */
|
||||
memcpy(val, &gre_info, sizeof(struct nhrp_gre_info));
|
||||
}
|
||||
} else {
|
||||
val = nhrp_gre_info_alloc(&gre_info);
|
||||
}
|
||||
ifp = if_lookup_by_index(gre_info.ifindex, vrf_id);
|
||||
debugf(NHRP_DEBUG_EVENT, "%s: gre interface %d vr %d obtained from system",
|
||||
ifp ? ifp->name : "<none>", gre_info.ifindex, vrf_id);
|
||||
if (ifp)
|
||||
nhrp_interface_update_nbma(ifp, val);
|
||||
return;
|
||||
stream_failure:
|
||||
zlog_err("%s(): error reading response ..", __func__);
|
||||
}
|
||||
|
|
|
@ -86,14 +86,22 @@ static inline int notifier_active(struct notifier_list *l)
|
|||
return !list_empty(&l->notifier_head);
|
||||
}
|
||||
|
||||
extern struct hash *nhrp_gre_list;
|
||||
|
||||
void nhrp_zebra_init(void);
|
||||
void nhrp_zebra_terminate(void);
|
||||
void nhrp_send_zebra_configure_arp(struct interface *ifp, int family);
|
||||
void nhrp_send_zebra_nbr(union sockunion *in,
|
||||
union sockunion *out,
|
||||
struct interface *ifp);
|
||||
void nhrp_send_zebra_configure_arp(struct interface *ifp,
|
||||
int family);
|
||||
|
||||
void nhrp_send_zebra_gre_source_set(struct interface *ifp,
|
||||
unsigned int link_idx,
|
||||
vrf_id_t link_vrf_id);
|
||||
|
||||
extern int nhrp_send_zebra_gre_request(struct interface *ifp);
|
||||
extern struct nhrp_gre_info *nhrp_gre_info_alloc(struct nhrp_gre_info *p);
|
||||
|
||||
struct zbuf;
|
||||
struct nhrp_vc;
|
||||
struct nhrp_cache;
|
||||
|
@ -300,8 +308,10 @@ struct nhrp_interface {
|
|||
char *ipsec_profile, *ipsec_fallback_profile, *source;
|
||||
union sockunion nbma;
|
||||
union sockunion nat_nbma;
|
||||
unsigned int linkidx;
|
||||
uint32_t grekey;
|
||||
unsigned int link_idx;
|
||||
unsigned int link_vrf_id;
|
||||
uint32_t i_grekey;
|
||||
uint32_t o_grekey;
|
||||
|
||||
struct hash *peer_hash;
|
||||
struct hash *cache_config_hash;
|
||||
|
@ -325,6 +335,18 @@ struct nhrp_interface {
|
|||
} afi[AFI_MAX];
|
||||
};
|
||||
|
||||
struct nhrp_gre_info {
|
||||
ifindex_t ifindex;
|
||||
struct in_addr vtep_ip; /* IFLA_GRE_LOCAL */
|
||||
struct in_addr vtep_ip_remote; /* IFLA_GRE_REMOTE */
|
||||
uint32_t ikey;
|
||||
uint32_t okey;
|
||||
ifindex_t ifindex_link; /* Interface index of interface
|
||||
* linked with GRE
|
||||
*/
|
||||
vrf_id_t vrfid_link;
|
||||
};
|
||||
|
||||
extern struct zebra_privs_t nhrpd_privs;
|
||||
|
||||
int sock_open_unix(const char *path);
|
||||
|
@ -332,6 +354,8 @@ int sock_open_unix(const char *path);
|
|||
void nhrp_interface_init(void);
|
||||
void nhrp_interface_update(struct interface *ifp);
|
||||
void nhrp_interface_update_mtu(struct interface *ifp, afi_t afi);
|
||||
void nhrp_interface_update_nbma(struct interface *ifp,
|
||||
struct nhrp_gre_info *gre_info);
|
||||
|
||||
int nhrp_interface_add(ZAPI_CALLBACK_ARGS);
|
||||
int nhrp_interface_delete(ZAPI_CALLBACK_ARGS);
|
||||
|
@ -340,6 +364,7 @@ int nhrp_interface_down(ZAPI_CALLBACK_ARGS);
|
|||
int nhrp_interface_address_add(ZAPI_CALLBACK_ARGS);
|
||||
int nhrp_interface_address_delete(ZAPI_CALLBACK_ARGS);
|
||||
void nhrp_neighbor_operation(ZAPI_CALLBACK_ARGS);
|
||||
void nhrp_gre_update(ZAPI_CALLBACK_ARGS);
|
||||
|
||||
void nhrp_interface_notify_add(struct interface *ifp, struct notifier_block *n,
|
||||
notifier_fn_t fn);
|
||||
|
|
|
@ -13,7 +13,6 @@ nhrpd_nhrpd_LDADD = lib/libfrr.la lib/libfrrcares.la $(LIBCAP)
|
|||
nhrpd_nhrpd_SOURCES = \
|
||||
nhrpd/linux.c \
|
||||
nhrpd/netlink_arp.c \
|
||||
nhrpd/netlink_gre.c \
|
||||
nhrpd/nhrp_cache.c \
|
||||
nhrpd/nhrp_errors.c \
|
||||
nhrpd/nhrp_event.c \
|
||||
|
|
|
@ -178,7 +178,7 @@ DEFPY (debug_zebra_mpls,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (debug_zebra_vxlan,
|
||||
DEFPY (debug_zebra_vxlan,
|
||||
debug_zebra_vxlan_cmd,
|
||||
"debug zebra vxlan",
|
||||
DEBUG_STR
|
||||
|
|
|
@ -29,10 +29,13 @@
|
|||
* Reference - https://sourceware.org/ml/libc-alpha/2013-01/msg00599.html
|
||||
*/
|
||||
#define _LINUX_IN6_H
|
||||
#define _LINUX_IF_H
|
||||
#define _LINUX_IP_H
|
||||
|
||||
#include <netinet/if_ether.h>
|
||||
#include <linux/if_bridge.h>
|
||||
#include <linux/if_link.h>
|
||||
#include <linux/if_tunnel.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/ethtool.h>
|
||||
|
@ -70,6 +73,7 @@
|
|||
#include "zebra/zebra_errors.h"
|
||||
#include "zebra/zebra_vxlan.h"
|
||||
#include "zebra/zebra_evpn_mh.h"
|
||||
#include "zebra/zebra_l2.h"
|
||||
|
||||
extern struct zebra_privs_t zserv_privs;
|
||||
|
||||
|
@ -289,6 +293,8 @@ static void netlink_determine_zebra_iftype(const char *kind,
|
|||
*zif_type = ZEBRA_IF_BOND;
|
||||
else if (strcmp(kind, "bond_slave") == 0)
|
||||
*zif_type = ZEBRA_IF_BOND_SLAVE;
|
||||
else if (strcmp(kind, "gre") == 0)
|
||||
*zif_type = ZEBRA_IF_GRE;
|
||||
}
|
||||
|
||||
#define parse_rtattr_nested(tb, max, rta) \
|
||||
|
@ -458,6 +464,80 @@ uint32_t kernel_get_speed(struct interface *ifp, int *error)
|
|||
return get_iflink_speed(ifp, error);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
netlink_gre_set_msg_encoder(struct zebra_dplane_ctx *ctx, void *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
struct {
|
||||
struct nlmsghdr n;
|
||||
struct ifinfomsg ifi;
|
||||
char buf[];
|
||||
} *req = buf;
|
||||
uint32_t link_idx;
|
||||
unsigned int mtu;
|
||||
struct rtattr *rta_info, *rta_data;
|
||||
const struct zebra_l2info_gre *gre_info;
|
||||
|
||||
if (buflen < sizeof(*req))
|
||||
return 0;
|
||||
memset(req, 0, sizeof(*req));
|
||||
|
||||
req->n.nlmsg_type = RTM_NEWLINK;
|
||||
req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||||
req->n.nlmsg_flags = NLM_F_REQUEST;
|
||||
|
||||
req->ifi.ifi_index = dplane_ctx_get_ifindex(ctx);
|
||||
|
||||
gre_info = dplane_ctx_gre_get_info(ctx);
|
||||
if (!gre_info)
|
||||
return 0;
|
||||
|
||||
req->ifi.ifi_change = 0xFFFFFFFF;
|
||||
link_idx = dplane_ctx_gre_get_link_ifindex(ctx);
|
||||
mtu = dplane_ctx_gre_get_mtu(ctx);
|
||||
|
||||
if (mtu && !nl_attr_put32(&req->n, buflen, IFLA_MTU, mtu))
|
||||
return 0;
|
||||
|
||||
rta_info = nl_attr_nest(&req->n, buflen, IFLA_LINKINFO);
|
||||
if (!rta_info)
|
||||
return 0;
|
||||
|
||||
if (!nl_attr_put(&req->n, buflen, IFLA_INFO_KIND, "gre", 3))
|
||||
return 0;
|
||||
|
||||
rta_data = nl_attr_nest(&req->n, buflen, IFLA_INFO_DATA);
|
||||
if (!rta_data)
|
||||
return 0;
|
||||
|
||||
if (!nl_attr_put32(&req->n, buflen, IFLA_GRE_LINK, link_idx))
|
||||
return 0;
|
||||
|
||||
if (gre_info->vtep_ip.s_addr &&
|
||||
!nl_attr_put32(&req->n, buflen, IFLA_GRE_LOCAL,
|
||||
gre_info->vtep_ip.s_addr))
|
||||
return 0;
|
||||
|
||||
if (gre_info->vtep_ip_remote.s_addr &&
|
||||
!nl_attr_put32(&req->n, buflen, IFLA_GRE_REMOTE,
|
||||
gre_info->vtep_ip_remote.s_addr))
|
||||
return 0;
|
||||
|
||||
if (gre_info->ikey &&
|
||||
!nl_attr_put32(&req->n, buflen, IFLA_GRE_IKEY,
|
||||
gre_info->ikey))
|
||||
return 0;
|
||||
if (gre_info->okey &&
|
||||
!nl_attr_put32(&req->n, buflen, IFLA_GRE_IKEY,
|
||||
gre_info->okey))
|
||||
return 0;
|
||||
|
||||
nl_attr_nest_end(&req->n, rta_data);
|
||||
nl_attr_nest_end(&req->n, rta_info);
|
||||
|
||||
return NLMSG_ALIGN(req->n.nlmsg_len);
|
||||
}
|
||||
|
||||
static int netlink_extract_bridge_info(struct rtattr *link_data,
|
||||
struct zebra_l2info_bridge *bridge_info)
|
||||
{
|
||||
|
@ -492,6 +572,47 @@ static int netlink_extract_vlan_info(struct rtattr *link_data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int netlink_extract_gre_info(struct rtattr *link_data,
|
||||
struct zebra_l2info_gre *gre_info)
|
||||
{
|
||||
struct rtattr *attr[IFLA_GRE_MAX + 1];
|
||||
|
||||
memset(gre_info, 0, sizeof(*gre_info));
|
||||
memset(attr, 0, sizeof(attr));
|
||||
parse_rtattr_nested(attr, IFLA_GRE_MAX, link_data);
|
||||
|
||||
if (!attr[IFLA_GRE_LOCAL]) {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"IFLA_GRE_LOCAL missing from GRE IF message");
|
||||
} else
|
||||
gre_info->vtep_ip =
|
||||
*(struct in_addr *)RTA_DATA(attr[IFLA_GRE_LOCAL]);
|
||||
if (!attr[IFLA_GRE_REMOTE]) {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"IFLA_GRE_REMOTE missing from GRE IF message");
|
||||
} else
|
||||
gre_info->vtep_ip_remote =
|
||||
*(struct in_addr *)RTA_DATA(attr[IFLA_GRE_REMOTE]);
|
||||
|
||||
if (!attr[IFLA_GRE_LINK]) {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug("IFLA_GRE_LINK missing from GRE IF message");
|
||||
} else {
|
||||
gre_info->ifindex_link =
|
||||
*(ifindex_t *)RTA_DATA(attr[IFLA_GRE_LINK]);
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug("IFLA_GRE_LINK obtained is %u",
|
||||
gre_info->ifindex_link);
|
||||
}
|
||||
if (attr[IFLA_GRE_IKEY])
|
||||
gre_info->ikey = *(uint32_t *)RTA_DATA(attr[IFLA_GRE_IKEY]);
|
||||
if (attr[IFLA_GRE_OKEY])
|
||||
gre_info->okey = *(uint32_t *)RTA_DATA(attr[IFLA_GRE_OKEY]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netlink_extract_vxlan_info(struct rtattr *link_data,
|
||||
struct zebra_l2info_vxlan *vxl_info)
|
||||
{
|
||||
|
@ -572,6 +693,16 @@ static void netlink_interface_update_l2info(struct interface *ifp,
|
|||
vxlan_info.ifindex_link)
|
||||
zebra_if_update_link(ifp, vxlan_info.ifindex_link,
|
||||
link_nsid);
|
||||
} else if (IS_ZEBRA_IF_GRE(ifp)) {
|
||||
struct zebra_l2info_gre gre_info;
|
||||
|
||||
netlink_extract_gre_info(link_data, &gre_info);
|
||||
gre_info.link_nsid = link_nsid;
|
||||
zebra_l2_greif_add_update(ifp, &gre_info, add);
|
||||
if (link_nsid != NS_UNKNOWN &&
|
||||
gre_info.ifindex_link)
|
||||
zebra_if_update_link(ifp, gre_info.ifindex_link,
|
||||
link_nsid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -934,6 +1065,20 @@ static int netlink_request_intf_addr(struct nlsock *netlink_cmd, int family,
|
|||
return netlink_request(netlink_cmd, &req);
|
||||
}
|
||||
|
||||
enum netlink_msg_status
|
||||
netlink_put_gre_set_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
enum dplane_op_e op;
|
||||
enum netlink_msg_status ret;
|
||||
|
||||
op = dplane_ctx_get_op(ctx);
|
||||
assert(op == DPLANE_OP_GRE_SET);
|
||||
|
||||
ret = netlink_batch_add_msg(bth, ctx, netlink_gre_set_msg_encoder, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Interface lookup by netlink socket. */
|
||||
int interface_lookup_netlink(struct zebra_ns *zns)
|
||||
{
|
||||
|
|
|
@ -32,6 +32,9 @@ extern int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id,
|
|||
extern int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup);
|
||||
extern int interface_lookup_netlink(struct zebra_ns *zns);
|
||||
|
||||
extern enum netlink_msg_status
|
||||
netlink_put_gre_set_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx);
|
||||
|
||||
extern enum netlink_msg_status
|
||||
netlink_put_address_update_msg(struct nl_batch *bth,
|
||||
struct zebra_dplane_ctx *ctx);
|
||||
|
|
|
@ -1066,8 +1066,9 @@ void if_up(struct interface *ifp)
|
|||
zif->link_ifindex);
|
||||
if (link_if)
|
||||
zebra_vxlan_svi_up(ifp, link_if);
|
||||
} else if (IS_ZEBRA_IF_MACVLAN(ifp))
|
||||
} else if (IS_ZEBRA_IF_MACVLAN(ifp)) {
|
||||
zebra_vxlan_macvlan_up(ifp);
|
||||
}
|
||||
|
||||
if (zif->es_info.es)
|
||||
zebra_evpn_es_if_oper_state_change(zif, true /*up*/);
|
||||
|
@ -1108,8 +1109,9 @@ void if_down(struct interface *ifp)
|
|||
zif->link_ifindex);
|
||||
if (link_if)
|
||||
zebra_vxlan_svi_down(ifp, link_if);
|
||||
} else if (IS_ZEBRA_IF_MACVLAN(ifp))
|
||||
} else if (IS_ZEBRA_IF_MACVLAN(ifp)) {
|
||||
zebra_vxlan_macvlan_down(ifp);
|
||||
}
|
||||
|
||||
if (zif->es_info.es)
|
||||
zebra_evpn_es_if_oper_state_change(zif, false /*up*/);
|
||||
|
@ -1305,6 +1307,9 @@ static const char *zebra_ziftype_2str(zebra_iftype_t zif_type)
|
|||
case ZEBRA_IF_MACVLAN:
|
||||
return "macvlan";
|
||||
|
||||
case ZEBRA_IF_GRE:
|
||||
return "GRE";
|
||||
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
|
@ -1577,6 +1582,28 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
|
|||
ifp->name);
|
||||
}
|
||||
vty_out(vty, "\n");
|
||||
} else if (IS_ZEBRA_IF_GRE(ifp)) {
|
||||
struct zebra_l2info_gre *gre_info;
|
||||
|
||||
gre_info = &zebra_if->l2info.gre;
|
||||
if (gre_info->vtep_ip.s_addr != INADDR_ANY) {
|
||||
vty_out(vty, " VTEP IP: %pI4", &gre_info->vtep_ip);
|
||||
if (gre_info->vtep_ip_remote.s_addr != INADDR_ANY)
|
||||
vty_out(vty, " , remote %pI4",
|
||||
&gre_info->vtep_ip_remote);
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
if (gre_info->ifindex_link &&
|
||||
(gre_info->link_nsid != NS_UNKNOWN)) {
|
||||
struct interface *ifp;
|
||||
|
||||
ifp = if_lookup_by_index_per_ns(
|
||||
zebra_ns_lookup(gre_info->link_nsid),
|
||||
gre_info->ifindex_link);
|
||||
vty_out(vty, " Link Interface %s\n",
|
||||
ifp == NULL ? "Unknown" :
|
||||
ifp->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) {
|
||||
|
|
|
@ -263,6 +263,7 @@ typedef enum {
|
|||
ZEBRA_IF_VETH, /* VETH interface*/
|
||||
ZEBRA_IF_BOND, /* Bond */
|
||||
ZEBRA_IF_BOND_SLAVE, /* Bond */
|
||||
ZEBRA_IF_GRE, /* GRE interface */
|
||||
} zebra_iftype_t;
|
||||
|
||||
/* Zebra "slave" interface type */
|
||||
|
@ -442,6 +443,9 @@ DECLARE_HOOK(zebra_if_config_wr, (struct vty * vty, struct interface *ifp),
|
|||
#define IS_ZEBRA_IF_BOND(ifp) \
|
||||
(((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_BOND)
|
||||
|
||||
#define IS_ZEBRA_IF_GRE(ifp) \
|
||||
(((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_GRE)
|
||||
|
||||
#define IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) \
|
||||
(((struct zebra_if *)(ifp->info))->zif_slave_type \
|
||||
== ZEBRA_IF_SLAVE_BRIDGE)
|
||||
|
|
|
@ -1360,6 +1360,9 @@ static enum netlink_msg_status nl_put_msg(struct nl_batch *bth,
|
|||
case DPLANE_OP_IPSET_ENTRY_DELETE:
|
||||
return FRR_NETLINK_ERROR;
|
||||
|
||||
case DPLANE_OP_GRE_SET:
|
||||
return netlink_put_gre_set_msg(bth, ctx);
|
||||
|
||||
case DPLANE_OP_NONE:
|
||||
return FRR_NETLINK_ERROR;
|
||||
}
|
||||
|
|
|
@ -81,9 +81,6 @@ extern int mpls_kernel_init(void);
|
|||
extern uint32_t kernel_get_speed(struct interface *ifp, int *error);
|
||||
extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute);
|
||||
|
||||
extern int kernel_configure_if_link(struct interface *ifp,
|
||||
struct interface *link_ifp, ns_id_t ns_id);
|
||||
|
||||
/*
|
||||
* Southbound Initialization routines to get initial starting
|
||||
* state.
|
||||
|
|
|
@ -394,12 +394,6 @@ enum zebra_dplane_result kernel_mac_update_ctx(struct zebra_dplane_ctx *ctx)
|
|||
return ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
}
|
||||
|
||||
int kernel_configure_if_link(struct interface *ifp, struct interface *link_ifp,
|
||||
ns_id_t ns_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int kernel_interface_set_master(struct interface *master,
|
||||
struct interface *slave)
|
||||
{
|
||||
|
|
108
zebra/zapi_msg.c
108
zebra/zapi_msg.c
|
@ -3240,6 +3240,61 @@ stream_failure:
|
|||
return;
|
||||
}
|
||||
|
||||
static inline void zebra_gre_get(ZAPI_HANDLER_ARGS)
|
||||
{
|
||||
struct stream *s;
|
||||
ifindex_t idx;
|
||||
struct interface *ifp;
|
||||
struct zebra_if *zebra_if = NULL;
|
||||
struct zebra_l2info_gre *gre_info;
|
||||
struct interface *ifp_link = NULL;
|
||||
vrf_id_t vrf_id_link = VRF_UNKNOWN;
|
||||
vrf_id_t vrf_id = zvrf->vrf->vrf_id;
|
||||
|
||||
s = msg;
|
||||
STREAM_GETL(s, idx);
|
||||
ifp = if_lookup_by_index(idx, vrf_id);
|
||||
|
||||
if (ifp)
|
||||
zebra_if = ifp->info;
|
||||
|
||||
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||
|
||||
zclient_create_header(s, ZEBRA_GRE_UPDATE, vrf_id);
|
||||
|
||||
if (ifp && IS_ZEBRA_IF_GRE(ifp) && zebra_if) {
|
||||
gre_info = &zebra_if->l2info.gre;
|
||||
|
||||
stream_putl(s, idx);
|
||||
stream_putl(s, gre_info->ikey);
|
||||
stream_putl(s, gre_info->ikey);
|
||||
stream_putl(s, gre_info->ifindex_link);
|
||||
|
||||
ifp_link = if_lookup_by_index_per_ns(
|
||||
zebra_ns_lookup(gre_info->link_nsid),
|
||||
gre_info->ifindex_link);
|
||||
if (ifp_link)
|
||||
vrf_id_link = ifp_link->vrf_id;
|
||||
stream_putl(s, vrf_id_link);
|
||||
stream_putl(s, gre_info->vtep_ip.s_addr);
|
||||
stream_putl(s, gre_info->vtep_ip_remote.s_addr);
|
||||
} else {
|
||||
stream_putl(s, idx);
|
||||
stream_putl(s, 0);
|
||||
stream_putl(s, 0);
|
||||
stream_putl(s, IFINDEX_INTERNAL);
|
||||
stream_putl(s, VRF_UNKNOWN);
|
||||
stream_putl(s, 0);
|
||||
}
|
||||
/* Write packet size. */
|
||||
stream_putw_at(s, 0, stream_get_endp(s));
|
||||
zserv_send_message(client, s);
|
||||
|
||||
return;
|
||||
stream_failure:
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void zebra_configure_arp(ZAPI_HANDLER_ARGS)
|
||||
{
|
||||
struct stream *s;
|
||||
|
@ -3373,6 +3428,57 @@ stream_failure:
|
|||
return;
|
||||
}
|
||||
|
||||
static inline void zebra_gre_source_set(ZAPI_HANDLER_ARGS)
|
||||
{
|
||||
struct stream *s;
|
||||
ifindex_t idx, link_idx;
|
||||
vrf_id_t link_vrf_id;
|
||||
struct interface *ifp;
|
||||
struct interface *ifp_link;
|
||||
vrf_id_t vrf_id = zvrf->vrf->vrf_id;
|
||||
struct zebra_if *zif, *gre_zif;
|
||||
struct zebra_l2info_gre *gre_info;
|
||||
unsigned int mtu;
|
||||
|
||||
s = msg;
|
||||
STREAM_GETL(s, idx);
|
||||
ifp = if_lookup_by_index(idx, vrf_id);
|
||||
STREAM_GETL(s, link_idx);
|
||||
STREAM_GETL(s, link_vrf_id);
|
||||
STREAM_GETL(s, mtu);
|
||||
|
||||
ifp_link = if_lookup_by_index(link_idx, link_vrf_id);
|
||||
if (!ifp_link || !ifp) {
|
||||
zlog_warn("GRE (index %u, VRF %u) or GRE link interface (index %u, VRF %u) not found, when setting GRE params",
|
||||
idx, vrf_id, link_idx, link_vrf_id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IS_ZEBRA_IF_GRE(ifp))
|
||||
return;
|
||||
|
||||
gre_zif = (struct zebra_if *)ifp->info;
|
||||
zif = (struct zebra_if *)ifp_link->info;
|
||||
if (!zif || !gre_zif)
|
||||
return;
|
||||
|
||||
gre_info = &zif->l2info.gre;
|
||||
if (!gre_info)
|
||||
return;
|
||||
|
||||
if (!mtu)
|
||||
mtu = ifp->mtu;
|
||||
|
||||
/* if gre link already set or mtu did not change, do not set it */
|
||||
if (gre_zif->link && gre_zif->link == ifp_link && mtu == ifp->mtu)
|
||||
return;
|
||||
|
||||
dplane_gre_set(ifp, ifp_link, mtu, gre_info);
|
||||
|
||||
stream_failure:
|
||||
return;
|
||||
}
|
||||
|
||||
static void zsend_error_msg(struct zserv *client, enum zebra_error_types error,
|
||||
struct zmsghdr *bad_hdr)
|
||||
{
|
||||
|
@ -3488,6 +3594,8 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
|
|||
[ZEBRA_NHRP_NEIGH_REGISTER] = zebra_neigh_register,
|
||||
[ZEBRA_NHRP_NEIGH_UNREGISTER] = zebra_neigh_unregister,
|
||||
[ZEBRA_CONFIGURE_ARP] = zebra_configure_arp,
|
||||
[ZEBRA_GRE_GET] = zebra_gre_get,
|
||||
[ZEBRA_GRE_SOURCE_SET] = zebra_gre_source_set,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -271,6 +271,11 @@ struct dplane_rule_info {
|
|||
struct dplane_ctx_rule old;
|
||||
};
|
||||
|
||||
struct dplane_gre_ctx {
|
||||
uint32_t link_ifindex;
|
||||
unsigned int mtu;
|
||||
struct zebra_l2info_gre info;
|
||||
};
|
||||
/*
|
||||
* The context block used to exchange info about route updates across
|
||||
* the boundary between the zebra main context (and pthread) and the
|
||||
|
@ -327,6 +332,7 @@ struct zebra_dplane_ctx {
|
|||
struct zebra_pbr_ipset_info info;
|
||||
} ipset_entry;
|
||||
struct dplane_neigh_table neightable;
|
||||
struct dplane_gre_ctx gre;
|
||||
} u;
|
||||
|
||||
/* Namespace info, used especially for netlink kernel communication */
|
||||
|
@ -469,6 +475,9 @@ static struct zebra_dplane_globals {
|
|||
_Atomic uint32_t dg_neightable_in;
|
||||
_Atomic uint32_t dg_neightable_errors;
|
||||
|
||||
_Atomic uint32_t dg_gre_set_in;
|
||||
_Atomic uint32_t dg_gre_set_errors;
|
||||
|
||||
/* Dataplane pthread */
|
||||
struct frr_pthread *dg_pthread;
|
||||
|
||||
|
@ -713,6 +722,9 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx)
|
|||
}
|
||||
list_delete(&ctx->u.iptable.interface_name_list);
|
||||
}
|
||||
break;
|
||||
case DPLANE_OP_GRE_SET:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -979,6 +991,10 @@ const char *dplane_op2str(enum dplane_op_e op)
|
|||
case DPLANE_OP_NEIGH_TABLE_UPDATE:
|
||||
ret = "NEIGH_TABLE_UPDATE";
|
||||
break;
|
||||
|
||||
case DPLANE_OP_GRE_SET:
|
||||
ret = "GRE_SET";
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -1772,6 +1788,31 @@ uint32_t dplane_ctx_neigh_get_update_flags(const struct zebra_dplane_ctx *ctx)
|
|||
return ctx->u.neigh.update_flags;
|
||||
}
|
||||
|
||||
/* Accessor for GRE set */
|
||||
uint32_t
|
||||
dplane_ctx_gre_get_link_ifindex(const struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
DPLANE_CTX_VALID(ctx);
|
||||
|
||||
return ctx->u.gre.link_ifindex;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
dplane_ctx_gre_get_mtu(const struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
DPLANE_CTX_VALID(ctx);
|
||||
|
||||
return ctx->u.gre.mtu;
|
||||
}
|
||||
|
||||
const struct zebra_l2info_gre *
|
||||
dplane_ctx_gre_get_info(const struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
DPLANE_CTX_VALID(ctx);
|
||||
|
||||
return &ctx->u.gre.info;
|
||||
}
|
||||
|
||||
/* Accessors for PBR rule information */
|
||||
int dplane_ctx_rule_get_sock(const struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
|
@ -4125,6 +4166,71 @@ dplane_pbr_ipset_entry_delete(struct zebra_pbr_ipset_entry *ipset)
|
|||
return ipset_entry_update_internal(DPLANE_OP_IPSET_ENTRY_DELETE, ipset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Common helper api for GRE set
|
||||
*/
|
||||
enum zebra_dplane_result
|
||||
dplane_gre_set(struct interface *ifp, struct interface *ifp_link,
|
||||
unsigned int mtu, const struct zebra_l2info_gre *gre_info)
|
||||
{
|
||||
enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
struct zebra_dplane_ctx *ctx;
|
||||
enum dplane_op_e op = DPLANE_OP_GRE_SET;
|
||||
int ret;
|
||||
struct zebra_ns *zns;
|
||||
|
||||
ctx = dplane_ctx_alloc();
|
||||
|
||||
if (!ifp)
|
||||
return result;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
|
||||
zlog_debug("init dplane ctx %s: if %s link %s%s",
|
||||
dplane_op2str(op), ifp->name,
|
||||
ifp_link ? "set" : "unset", ifp_link ?
|
||||
ifp_link->name : "");
|
||||
}
|
||||
|
||||
ctx->zd_op = op;
|
||||
ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
zns = zebra_ns_lookup(ifp->vrf_id);
|
||||
if (!zns)
|
||||
return result;
|
||||
dplane_ctx_ns_init(ctx, zns, false);
|
||||
|
||||
dplane_ctx_set_ifname(ctx, ifp->name);
|
||||
ctx->zd_vrf_id = ifp->vrf_id;
|
||||
ctx->zd_ifindex = ifp->ifindex;
|
||||
if (ifp_link)
|
||||
ctx->u.gre.link_ifindex = ifp_link->ifindex;
|
||||
else
|
||||
ctx->u.gre.link_ifindex = 0;
|
||||
if (gre_info)
|
||||
memcpy(&ctx->u.gre.info, gre_info, sizeof(ctx->u.gre.info));
|
||||
ctx->u.gre.mtu = mtu;
|
||||
|
||||
ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
|
||||
/* Enqueue context for processing */
|
||||
ret = dplane_update_enqueue(ctx);
|
||||
|
||||
/* Update counter */
|
||||
atomic_fetch_add_explicit(&zdplane_info.dg_gre_set_in, 1,
|
||||
memory_order_relaxed);
|
||||
|
||||
if (ret == AOK)
|
||||
result = ZEBRA_DPLANE_REQUEST_QUEUED;
|
||||
else {
|
||||
atomic_fetch_add_explicit(
|
||||
&zdplane_info.dg_gre_set_errors, 1,
|
||||
memory_order_relaxed);
|
||||
if (ctx)
|
||||
dplane_ctx_free(&ctx);
|
||||
result = ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for 'show dplane'
|
||||
*/
|
||||
|
@ -4234,6 +4340,13 @@ int dplane_show_helper(struct vty *vty, bool detailed)
|
|||
memory_order_relaxed);
|
||||
vty_out(vty, "Neighbor Table updates: %"PRIu64"\n", incoming);
|
||||
vty_out(vty, "Neighbor Table errors: %"PRIu64"\n", errs);
|
||||
|
||||
incoming = atomic_load_explicit(&zdplane_info.dg_gre_set_in,
|
||||
memory_order_relaxed);
|
||||
errs = atomic_load_explicit(&zdplane_info.dg_gre_set_errors,
|
||||
memory_order_relaxed);
|
||||
vty_out(vty, "GRE set updates: %"PRIu64"\n", incoming);
|
||||
vty_out(vty, "GRE set errors: %"PRIu64"\n", errs);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -4680,6 +4793,12 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx)
|
|||
dplane_ctx_get_ifname(ctx),
|
||||
family2str(dplane_ctx_neightable_get_family(ctx)));
|
||||
break;
|
||||
case DPLANE_OP_GRE_SET:
|
||||
zlog_debug("Dplane gre set op %s, ifp %s, link %u",
|
||||
dplane_op2str(dplane_ctx_get_op(ctx)),
|
||||
dplane_ctx_get_ifname(ctx),
|
||||
ctx->u.gre.link_ifindex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4808,6 +4927,12 @@ static void kernel_dplane_handle_result(struct zebra_dplane_ctx *ctx)
|
|||
memory_order_relaxed);
|
||||
break;
|
||||
|
||||
case DPLANE_OP_GRE_SET:
|
||||
if (res != ZEBRA_DPLANE_REQUEST_SUCCESS)
|
||||
atomic_fetch_add_explicit(
|
||||
&zdplane_info.dg_gre_set_errors, 1,
|
||||
memory_order_relaxed);
|
||||
break;
|
||||
/* Ignore 'notifications' - no-op */
|
||||
case DPLANE_OP_SYS_ROUTE_ADD:
|
||||
case DPLANE_OP_SYS_ROUTE_DELETE:
|
||||
|
|
|
@ -171,6 +171,7 @@ enum dplane_op_e {
|
|||
DPLANE_OP_NEIGH_IP_DELETE,
|
||||
|
||||
DPLANE_OP_NEIGH_TABLE_UPDATE,
|
||||
DPLANE_OP_GRE_SET,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -527,6 +528,14 @@ dplane_ctx_neightable_get_mcast_probes(const struct zebra_dplane_ctx *ctx);
|
|||
uint32_t
|
||||
dplane_ctx_neightable_get_ucast_probes(const struct zebra_dplane_ctx *ctx);
|
||||
|
||||
/* Accessor for GRE set */
|
||||
uint32_t
|
||||
dplane_ctx_gre_get_link_ifindex(const struct zebra_dplane_ctx *ctx);
|
||||
unsigned int
|
||||
dplane_ctx_gre_get_mtu(const struct zebra_dplane_ctx *ctx);
|
||||
const struct zebra_l2info_gre *
|
||||
dplane_ctx_gre_get_info(const struct zebra_dplane_ctx *ctx);
|
||||
|
||||
/* Namespace info - esp. for netlink communication */
|
||||
const struct zebra_dplane_info *dplane_ctx_get_ns(
|
||||
const struct zebra_dplane_ctx *ctx);
|
||||
|
@ -695,6 +704,13 @@ enum zebra_dplane_result dplane_neigh_table_update(const struct interface *ifp,
|
|||
const uint32_t ucast_probes,
|
||||
const uint32_t mcast_probes);
|
||||
|
||||
/*
|
||||
* Enqueue a GRE set
|
||||
*/
|
||||
enum zebra_dplane_result
|
||||
dplane_gre_set(struct interface *ifp, struct interface *ifp_link,
|
||||
unsigned int mtu, const struct zebra_l2info_gre *gre_info);
|
||||
|
||||
/* Forward ref of zebra_pbr_rule */
|
||||
struct zebra_pbr_rule;
|
||||
|
||||
|
|
|
@ -134,6 +134,7 @@ enum zebra_log_refs {
|
|||
EC_ZEBRA_DUPLICATE_NHG_MESSAGE,
|
||||
EC_ZEBRA_VRF_MISCONFIGURED,
|
||||
EC_ZEBRA_ES_CREATE,
|
||||
EC_ZEBRA_GRE_SET_UPDATE,
|
||||
};
|
||||
|
||||
void zebra_error_init(void);
|
||||
|
|
|
@ -289,6 +289,32 @@ void zebra_l2_vlanif_update(struct interface *ifp,
|
|||
memcpy(&zif->l2info.vl, vlan_info, sizeof(*vlan_info));
|
||||
}
|
||||
|
||||
/*
|
||||
* Update L2 info for a GRE interface. This is called upon interface
|
||||
* addition as well as update. Upon add/update, need to inform
|
||||
* clients about GRE information.
|
||||
*/
|
||||
void zebra_l2_greif_add_update(struct interface *ifp,
|
||||
struct zebra_l2info_gre *gre_info, int add)
|
||||
{
|
||||
struct zebra_if *zif;
|
||||
struct in_addr old_vtep_ip;
|
||||
|
||||
zif = ifp->info;
|
||||
assert(zif);
|
||||
|
||||
if (add) {
|
||||
memcpy(&zif->l2info.gre, gre_info, sizeof(*gre_info));
|
||||
return;
|
||||
}
|
||||
|
||||
old_vtep_ip = zif->l2info.gre.vtep_ip;
|
||||
if (IPV4_ADDR_SAME(&old_vtep_ip, &gre_info->vtep_ip))
|
||||
return;
|
||||
|
||||
zif->l2info.gre.vtep_ip = gre_info->vtep_ip;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update L2 info for a VxLAN interface. This is called upon interface
|
||||
* addition as well as update. Upon add, need to invoke the VNI create
|
||||
|
|
|
@ -54,6 +54,18 @@ struct zebra_l2info_vlan {
|
|||
vlanid_t vid; /* VLAN id */
|
||||
};
|
||||
|
||||
/* zebra L2 interface information - GRE interface */
|
||||
struct zebra_l2info_gre {
|
||||
struct in_addr vtep_ip; /* IFLA_GRE_LOCAL */
|
||||
struct in_addr vtep_ip_remote; /* IFLA_GRE_REMOTE */
|
||||
uint32_t ikey;
|
||||
uint32_t okey;
|
||||
ifindex_t ifindex_link; /* Interface index of interface
|
||||
* linked with GRE
|
||||
*/
|
||||
ns_id_t link_nsid;
|
||||
};
|
||||
|
||||
/* zebra L2 interface information - VXLAN interface */
|
||||
struct zebra_l2info_vxlan {
|
||||
vni_t vni; /* VNI */
|
||||
|
@ -75,6 +87,7 @@ union zebra_l2if_info {
|
|||
struct zebra_l2info_bridge br;
|
||||
struct zebra_l2info_vlan vl;
|
||||
struct zebra_l2info_vxlan vxl;
|
||||
struct zebra_l2info_gre gre;
|
||||
};
|
||||
|
||||
/* NOTE: These macros are to be invoked only in the "correct" context.
|
||||
|
@ -96,11 +109,15 @@ extern void zebra_l2_bridge_add_update(struct interface *ifp,
|
|||
extern void zebra_l2_bridge_del(struct interface *ifp);
|
||||
extern void zebra_l2_vlanif_update(struct interface *ifp,
|
||||
struct zebra_l2info_vlan *vlan_info);
|
||||
extern void zebra_l2_greif_add_update(struct interface *ifp,
|
||||
struct zebra_l2info_gre *vxlan_info,
|
||||
int add);
|
||||
extern void zebra_l2_vxlanif_add_update(struct interface *ifp,
|
||||
struct zebra_l2info_vxlan *vxlan_info,
|
||||
int add);
|
||||
extern void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
|
||||
vlanid_t access_vlan);
|
||||
extern void zebra_l2_greif_del(struct interface *ifp);
|
||||
extern void zebra_l2_vxlanif_del(struct interface *ifp);
|
||||
extern void zebra_l2if_update_bridge_slave(struct interface *ifp,
|
||||
ifindex_t bridge_ifindex,
|
||||
|
|
|
@ -2965,6 +2965,7 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx)
|
|||
case DPLANE_OP_IPSET_ENTRY_ADD:
|
||||
case DPLANE_OP_IPSET_ENTRY_DELETE:
|
||||
case DPLANE_OP_NEIGH_TABLE_UPDATE:
|
||||
case DPLANE_OP_GRE_SET:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -4062,6 +4062,7 @@ static int rib_process_dplane_results(struct thread *thread)
|
|||
case DPLANE_OP_NEIGH_DISCOVER:
|
||||
case DPLANE_OP_BR_PORT_UPDATE:
|
||||
case DPLANE_OP_NEIGH_TABLE_UPDATE:
|
||||
case DPLANE_OP_GRE_SET:
|
||||
case DPLANE_OP_NONE:
|
||||
/* Don't expect this: just return the struct? */
|
||||
dplane_ctx_fini(&ctx);
|
||||
|
|
Loading…
Reference in a new issue