summaryrefslogtreecommitdiffstats
path: root/zebra/zebra_vxlan.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--zebra/zebra_vxlan.c227
1 files changed, 130 insertions, 97 deletions
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 50a7462..2ffaefd 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -82,7 +82,7 @@ static int zl3vni_nh_uninstall(struct zebra_l3vni *zl3vni,
struct zebra_neigh *n);
static struct zebra_neigh *svd_nh_add(const struct ipaddr *vtep_ip,
const struct ethaddr *rmac);
-static int svd_nh_del(struct zebra_neigh *n);
+static void svd_nh_del(struct zebra_neigh *n);
static int svd_nh_install(struct zebra_l3vni *zl3vni, struct zebra_neigh *n);
static int svd_nh_uninstall(struct zebra_l3vni *zl3vni, struct zebra_neigh *n);
@@ -308,7 +308,7 @@ static void zevpn_print_neigh_hash_all_evpn_detail(struct hash_bucket *bucket,
zevpn = (struct zebra_evpn *)bucket->data;
if (!zevpn) {
if (json)
- vty_out(vty, "{}\n");
+ vty_json_empty(vty, json);
return;
}
num_neigh = hashcount(zevpn->neigh_table);
@@ -515,7 +515,7 @@ static void zevpn_print_mac_hash_all_evpn_detail(struct hash_bucket *bucket,
zevpn = (struct zebra_evpn *)bucket->data;
if (!zevpn) {
if (json)
- vty_out(vty, "{}\n");
+ vty_json_empty(vty, json);
return;
}
wctx->zevpn = zevpn;
@@ -1590,17 +1590,24 @@ static struct zebra_neigh *svd_nh_add(const struct ipaddr *ip,
/*
* Del Single VXlan Device neighbor entry.
*/
-static int svd_nh_del(struct zebra_neigh *n)
+static void svd_nh_del(struct zebra_neigh *n)
{
if (n->refcnt > 0)
- return -1;
+ return;
hash_release(svd_nh_table, n);
XFREE(MTYPE_L3NEIGH, n);
+}
- return 0;
+static void svd_nh_del_terminate(void *ptr)
+{
+ struct zebra_neigh *n = ptr;
+
+ n->refcnt = 0;
+ svd_nh_del(n);
}
+
/*
* Common code to install remote nh as neigh into the kernel.
*/
@@ -2258,14 +2265,13 @@ static int zl3vni_send_add_to_client(struct zebra_l3vni *zl3vni)
stream_putw_at(s, 0, stream_get_endp(s));
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug(
- "Send L3_VNI_ADD %u VRF %s RMAC %pEA VRR %pEA local-ip %pI4 filter %s to %s",
- zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
- &svi_rmac, &vrr_rmac, &zl3vni->local_vtep_ip,
- CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
- ? "prefix-routes-only"
- : "none",
- zebra_route_string(client->proto));
+ zlog_debug("Send L3VNI ADD %u VRF %s RMAC %pEA VRR %pEA local-ip %pI4 filter %s to %s",
+ zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
+ &svi_rmac, &vrr_rmac, &zl3vni->local_vtep_ip,
+ CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
+ ? "prefix-routes-only"
+ : "none",
+ zebra_route_string(client->proto));
client->l3vniadd_cnt++;
return zserv_send_message(client, s);
@@ -2293,7 +2299,7 @@ static int zl3vni_send_del_to_client(struct zebra_l3vni *zl3vni)
stream_putw_at(s, 0, stream_get_endp(s));
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("Send L3_VNI_DEL %u VRF %s to %s", zl3vni->vni,
+ zlog_debug("Send L3VNI DEL %u VRF %s to %s", zl3vni->vni,
vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
zebra_route_string(client->proto));
@@ -2590,14 +2596,15 @@ void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
zl3vni = zl3vni_lookup(l3vni);
if (!zl3vni) {
if (use_json)
- vty_json(vty, json);
+ vty_json_empty(vty, json);
else
vty_out(vty, "%% L3-VNI %u doesn't exist\n", l3vni);
return;
@@ -2631,14 +2638,15 @@ void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
zl3vni = zl3vni_lookup(l3vni);
if (!zl3vni) {
if (use_json)
- vty_json(vty, json);
+ vty_json_empty(vty, json);
else
vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
return;
@@ -2672,7 +2680,8 @@ void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json)
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
@@ -2698,7 +2707,8 @@ void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
@@ -2709,7 +2719,7 @@ void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni,
zl3vni = zl3vni_lookup(l3vni);
if (!zl3vni) {
if (use_json)
- vty_out(vty, "{}\n");
+ vty_json(vty, json);
else
vty_out(vty, "%% L3-VNI %u does not exist\n",
l3vni);
@@ -2721,7 +2731,7 @@ void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni,
if (!n) {
if (use_json)
- vty_out(vty, "{}\n");
+ vty_json_empty(vty, json);
else
vty_out(vty,
"%% Requested next-hop not present for L3-VNI %u\n",
@@ -2742,13 +2752,16 @@ static void l3vni_print_nh_table(struct hash *nh_table, struct vty *vty,
struct nh_walk_ctx wctx;
json_object *json = NULL;
- num_nh = hashcount(nh_table);
- if (!num_nh)
- return;
-
if (use_json)
json = json_object_new_object();
+ num_nh = hashcount(nh_table);
+ if (!num_nh) {
+ if (use_json)
+ vty_json_empty(vty, json);
+ return;
+ }
+
wctx.vty = vty;
wctx.json = json;
if (!use_json) {
@@ -2770,14 +2783,14 @@ void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
if (!is_evpn_enabled()) {
if (use_json)
- vty_out(vty, "{}\n");
+ vty_json_empty(vty, NULL);
return;
}
zl3vni = zl3vni_lookup(l3vni);
if (!zl3vni) {
if (use_json)
- vty_out(vty, "{}\n");
+ vty_json_empty(vty, NULL);
else
vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
return;
@@ -2790,7 +2803,7 @@ void zebra_vxlan_print_nh_svd(struct vty *vty, bool use_json)
{
if (!is_evpn_enabled()) {
if (use_json)
- vty_out(vty, "{}\n");
+ vty_json_empty(vty, NULL);
return;
}
@@ -2806,7 +2819,8 @@ void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json)
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
@@ -2834,14 +2848,15 @@ void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json)
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
zl3vni = zl3vni_lookup(vni);
if (!zl3vni) {
if (use_json)
- vty_json(vty, json);
+ vty_json_empty(vty, json);
else
vty_out(vty, "%% VNI %u does not exist\n", vni);
return;
@@ -2905,14 +2920,15 @@ void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
zevpn = zebra_evpn_lookup(vni);
if (!zevpn) {
if (use_json)
- vty_json(vty, json);
+ vty_json_empty(vty, json);
else
vty_out(vty, "%% VNI %u does not exist\n", vni);
return;
@@ -2959,7 +2975,8 @@ void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
@@ -2989,7 +3006,8 @@ void zebra_vxlan_print_neigh_all_vni_detail(struct vty *vty,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
@@ -3020,14 +3038,15 @@ void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
zevpn = zebra_evpn_lookup(vni);
if (!zevpn) {
if (use_json)
- vty_json(vty, json);
+ vty_json_empty(vty, json);
else
vty_out(vty, "%% VNI %u does not exist\n", vni);
return;
@@ -3064,14 +3083,15 @@ void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
zevpn = zebra_evpn_lookup(vni);
if (!zevpn) {
if (use_json)
- vty_json(vty, json);
+ vty_json_empty(vty, json);
else
vty_out(vty, "%% VNI %u does not exist\n", vni);
return;
@@ -3113,14 +3133,15 @@ void zebra_vxlan_print_neigh_vni_dad(struct vty *vty,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
zevpn = zebra_evpn_lookup(vni);
if (!zevpn) {
if (use_json)
- vty_json(vty, json);
+ vty_json_empty(vty, json);
else
vty_out(vty, "%% VNI %u does not exist\n", vni);
return;
@@ -3177,21 +3198,24 @@ void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
if (!is_evpn_enabled()) {
if (use_json)
- vty_out(vty, "{}\n");
+ vty_json_empty(vty, NULL);
return;
}
zevpn = zebra_evpn_lookup(vni);
if (!zevpn) {
if (use_json)
- vty_out(vty, "{}\n");
+ vty_json_empty(vty, NULL);
else
vty_out(vty, "%% VNI %u does not exist\n", vni);
return;
}
num_macs = num_valid_macs(zevpn);
- if (!num_macs)
+ if (!num_macs) {
+ if (use_json)
+ vty_json_empty(vty, NULL);
return;
+ }
if (use_json) {
json = json_object_new_object();
@@ -3250,7 +3274,8 @@ void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
@@ -3278,7 +3303,8 @@ void zebra_vxlan_print_macs_all_vni_detail(struct vty *vty,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
@@ -3307,7 +3333,8 @@ void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
@@ -3337,7 +3364,8 @@ void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
@@ -3377,22 +3405,34 @@ void zebra_vxlan_print_macs_vni_dad(struct vty *vty,
json_object *json = NULL;
json_object *json_mac = NULL;
- if (!is_evpn_enabled())
+ if (!is_evpn_enabled()) {
+ if (use_json)
+ vty_json_empty(vty, NULL);
return;
+ }
zevpn = zebra_evpn_lookup(vni);
if (!zevpn) {
- vty_out(vty, "%% VNI %u does not exist\n", vni);
+ if (use_json)
+ vty_json_empty(vty, NULL);
+ else
+ vty_out(vty, "%% VNI %u does not exist\n", vni);
return;
}
num_macs = num_valid_macs(zevpn);
- if (!num_macs)
+ if (!num_macs) {
+ if (use_json)
+ vty_json_empty(vty, NULL);
return;
+ }
num_macs = num_dup_detected_macs(zevpn);
- if (!num_macs)
+ if (!num_macs) {
+ if (use_json)
+ vty_json_empty(vty, NULL);
return;
+ }
if (use_json) {
json = json_object_new_object();
@@ -3727,21 +3767,25 @@ void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
json_object *json_mac = NULL;
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, NULL);
return;
}
zevpn = zebra_evpn_lookup(vni);
if (!zevpn) {
if (use_json)
- vty_out(vty, "{}\n");
+ vty_json_empty(vty, NULL);
else
vty_out(vty, "%% VNI %u does not exist\n", vni);
return;
}
num_macs = num_valid_macs(zevpn);
- if (!num_macs)
+ if (!num_macs) {
+ if (use_json)
+ vty_json_empty(vty, NULL);
return;
+ }
if (use_json) {
json = json_object_new_object();
@@ -3785,7 +3829,8 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
@@ -3829,7 +3874,8 @@ void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (uj)
+ vty_json(vty, json);
return;
}
@@ -3906,7 +3952,8 @@ void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
json = json_object_new_object();
if (!is_evpn_enabled()) {
- vty_json(vty, json);
+ if (use_json)
+ vty_json_empty(vty, json);
return;
}
@@ -3990,7 +4037,7 @@ void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf,
if (!is_evpn_enabled()) {
if (use_json)
- vty_out(vty, "{}\n");
+ vty_json_empty(vty, NULL);
return;
}
@@ -5110,7 +5157,21 @@ void zebra_vxlan_macvlan_up(struct interface *ifp)
zif = ifp->info;
assert(zif);
+
+ if (zif->link_nsid)
+ /* the link interface is another namespace */
+ return;
+
link_ifp = zif->link;
+ if (!link_ifp) {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug(
+ "macvlan parent link is not found. Parent index %d ifp %s",
+ zif->link_ifindex,
+ ifindex2ifname(zif->link_ifindex,
+ ifp->vrf->vrf_id));
+ return;
+ }
link_zif = link_ifp->info;
assert(link_zif);
@@ -5127,9 +5188,8 @@ void zebra_vxlan_macvlan_up(struct interface *ifp)
}
}
-int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
- char *err, int err_str_sz, int filter,
- int add)
+void zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
+ int filter, int add)
{
struct zebra_l3vni *zl3vni = NULL;
struct zebra_vrf *zvrf_evpn = NULL;
@@ -5141,21 +5201,6 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
add ? "ADD" : "DEL");
if (add) {
- /* check if the vni is already present under zvrf */
- if (zvrf->l3vni) {
- snprintf(err, err_str_sz,
- "VNI is already configured under the vrf");
- return -1;
- }
-
- /* check if this VNI is already present in the system */
- zl3vni = zl3vni_lookup(vni);
- if (zl3vni) {
- snprintf(err, err_str_sz,
- "VNI is already configured as L3-VNI");
- return -1;
- }
-
/* Remove L2VNI if present */
zebra_vxlan_handle_vni_transition(zvrf, vni, add);
@@ -5201,23 +5246,7 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
} else {
zl3vni = zl3vni_lookup(vni);
- if (!zl3vni) {
- snprintf(err, err_str_sz, "VNI doesn't exist");
- return -1;
- }
-
- if (zvrf->l3vni != vni) {
- snprintf(err, err_str_sz,
- "VNI %d doesn't exist in VRF: %s",
- vni, zvrf->vrf->name);
- return -1;
- }
-
- if (filter && !CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)) {
- snprintf(err, ERR_STR_SZ,
- "prefix-routes-only is not set for the vni");
- return -1;
- }
+ assert(zl3vni);
zebra_vxlan_process_l3vni_oper_down(zl3vni);
@@ -5235,7 +5264,6 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
/* Add L2VNI for this VNI */
zebra_vxlan_handle_vni_transition(zvrf, vni, add);
}
- return 0;
}
int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf)
@@ -5772,6 +5800,11 @@ void zebra_vxlan_init(void)
zebra_evpn_mh_init();
}
+void zebra_vxlan_terminate(void)
+{
+ hash_clean_and_free(&svd_nh_table, svd_nh_del_terminate);
+}
+
/* free l3vni table */
void zebra_vxlan_disable(void)
{