Files
lcpng/lcpng_nl_sync.c
Pim van Pelt 45f4088656 Add ability to create subint's from Linux
Using the earlier placeholder hint in lcp_nl_link_add(), I know that
I've gotten a NEWLINK request but the linux ifindex doesn't have a LIP.

This could be because the interface is entirely foreign to VPP, for
example somebody created a dummy interface or a VLAN subint on one:
ip link add dum0 type dummy
ip link add link dum0 name dum0.10 type vlan id 10

Or, I'm actually trying to create a VLAN subint, like these:
ip link add link e0 name e0.1234 type vlan id 1234
ip link add link e0.1234 name e0.1235 type vlan id 1000
ip link add link e0 name e0.1236 type vlan id 2345 proto 802.1ad
ip link add link e0.1236 name e0.1237 type vlan id 1000

None of these NEWLINK callbacks, represented by vif (linux interface
id) will have a corresponding LIP. So, I try to create one by calling
lcp_nl_link_add_vlan().

Here, I lookup the parent index ('dum0' or 'e0' in the first examples),
the former of which also doesn't have a LIP, so I bail. If it does,
I still have two choices:
1) the LIP is a phy (ie TenGigabitEthernet3/0/0) and this is a regular
   tagged interface; or
2) the LIP is itself a subint (ie TenGigabitEthernet3/0/0.1234) and
   what I'm asking for is a QinQ or QinAD sub-interface.

So I look up as well the phy LIP. We now have all the ingredients I
need to create the VPP sub-interfaces with the correct inner-dot1q
and outer dot1q or dot1ad.

Of course, I don't really know what subinterface ID to use. It's
appealing to "just" use the vlan, but that's not helpful if the outer
tag and the inner tag are the same. So I write a helper function
vnet_sw_interface_get_available_subid() whose job it is to return an
unused subid for the phy -- starting from 1.

I then create the phy sub-interface and the tap sub-interface,
tying them together into a new LIP. During these interface creations, I
want to make sure that if lcp-auto-subint is on, we disable that. I
don't want VPP racing to create LIPs for the sub-ints right now. Before
I return (either in error state or upon success), I put back the
lcp-auto-subint to what it was before.

If I manage to create the LIP, huzzah. I return it to the caller so it
can continue setting link/mac/mtu etc.
2021-08-24 23:40:14 +02:00

621 lines
18 KiB
C

/* Hey Emacs use -*- mode: C -*- */
/*
* Copyright 2021 Cisco and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sys/socket.h>
#include <linux/if.h>
#include <vnet/vnet.h>
#include <vnet/plugin/plugin.h>
#include <vppinfra/linux/netns.h>
#include <linux/if_ether.h>
#include <plugins/lcpng/lcpng_interface.h>
#include <plugins/lcpng/lcpng_netlink.h>
#include <vnet/fib/fib_table.h>
#include <vnet/mfib/mfib_table.h>
#include <vnet/ip/ip6_ll_table.h>
#include <vnet/ip-neighbor/ip_neighbor.h>
#include <vnet/ip/ip6_link.h>
#ifndef NUD_VALID
#define NUD_VALID \
(NUD_PERMANENT | NUD_NOARP | NUD_REACHABLE | NUD_PROBE | NUD_STALE | \
NUD_DELAY)
#endif
static void
lcp_nl_mk_ip_addr (const struct nl_addr *rna, ip_address_t *ia)
{
ip_address_reset (ia);
ip_address_set (ia, nl_addr_get_binary_addr (rna),
nl_addr_get_family (rna) == AF_INET6 ? AF_IP6 : AF_IP4);
}
static void
lcp_nl_mk_mac_addr (const struct nl_addr *rna, mac_address_t *mac)
{
mac_address_from_bytes (mac, nl_addr_get_binary_addr (rna));
}
static int
vnet_sw_interface_subid_exists (vnet_main_t *vnm, u32 sw_if_index, u32 id)
{
u64 sup_and_sub_key = ((u64) (sw_if_index) << 32) | (u64) id;
vnet_interface_main_t *im = &vnm->interface_main;
uword *p;
p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
if (p)
return 1;
return 0;
}
static int
vnet_sw_interface_get_available_subid (vnet_main_t *vnm, u32 sw_if_index,
u32 *id)
{
u32 i;
for (i = 1; i < 4096; i++)
{
if (!vnet_sw_interface_subid_exists (vnm, sw_if_index, i))
{
*id = i;
return 0;
}
}
*id = -1;
return 1;
}
// Returns the LIP for a newly created sub-int pair, or
// NULL in case no sub-int could be created.
static lcp_itf_pair_t *
lcp_nl_link_add_vlan (struct rtnl_link *rl)
{
vnet_main_t *vnm = vnet_get_main ();
int parent_idx, idx;
lcp_itf_pair_t *parent_lip, *phy_lip;
vnet_sw_interface_t *parent_sw;
int vlan;
u32 proto;
u32 subid;
u32 inner_vlan, outer_vlan, flags;
u32 phy_sw_if_index, host_sw_if_index;
lcp_main_t *lcpm = &lcp_main;
u8 old_lcp_auto_subint;
if (!rtnl_link_is_vlan (rl))
return NULL;
idx = rtnl_link_get_ifindex (rl);
parent_idx = rtnl_link_get_link (rl);
vlan = rtnl_link_vlan_get_id (rl);
proto = rtnl_link_vlan_get_protocol (rl);
/* Get the LIP of the parent, can be a phy Te3/0/0 or a subint Te3/0/0.1000
*/
if (!(parent_lip = lcp_itf_pair_get (lcp_itf_pair_find_by_vif (parent_idx))))
{
NL_WARN ("link_add_vlan: no LCP for parent of %U", format_nl_object, rl);
return NULL;
}
parent_sw = vnet_get_sw_interface (vnm, parent_lip->lip_phy_sw_if_index);
if (!parent_sw)
{
NL_ERROR ("link_add_vlan: Cannot get parent of %U", format_lcp_itf_pair,
parent_lip);
return NULL;
}
/* Get the LIP of the phy, ie "phy TenGigabitEthernet3/0/0 host tap1 host-if
* e0" */
phy_lip =
lcp_itf_pair_get (lcp_itf_pair_find_by_phy (parent_sw->sup_sw_if_index));
if (vnet_sw_interface_is_sub (vnm, parent_lip->lip_phy_sw_if_index))
{
// QinQ or QinAD
inner_vlan = vlan;
outer_vlan = parent_sw->sub.eth.outer_vlan_id;
if (ntohs (proto) == ETH_P_8021AD)
{
NL_ERROR ("link_add_vlan: cannot create inner dot1ad: %U",
format_nl_object, rl);
return NULL;
}
}
else
{
inner_vlan = 0;
outer_vlan = vlan;
}
// Flags: no_tags(1), one_tag(2), two_tags(4), dot1ad(8), exact_match(16) see
// vnet/interface.h
flags = 16; // exact-match
if ((parent_sw->sub.eth.flags.dot1ad) || (ntohs (proto) == ETH_P_8021AD))
flags += 8; // dot1ad
if (inner_vlan)
flags += 4; // two_tags
else
flags += 2; // one_tag
/* Create sub on the phy and on the tap, but avoid triggering sub-int
* autocreation if it's enabled.
*/
old_lcp_auto_subint = lcpm->lcp_auto_subint;
lcpm->lcp_auto_subint = 0;
/* Generate a subid, take the first available one */
if (vnet_sw_interface_get_available_subid (vnm, parent_sw->sup_sw_if_index,
&subid))
{
NL_ERROR ("link_add_vlan: cannot find available subid on phy %U",
format_vnet_sw_if_index_name, vnm, parent_sw->sup_sw_if_index);
lcpm->lcp_auto_subint = old_lcp_auto_subint;
return NULL;
}
vlib_worker_thread_barrier_sync (vlib_get_main ());
NL_NOTICE (
"link_add_vlan: creating subid %u outer %u inner %u flags %u on phy %U",
subid, outer_vlan, inner_vlan, flags, format_vnet_sw_if_index_name, vnm,
parent_sw->sup_sw_if_index);
if (vnet_create_sub_interface (parent_sw->sup_sw_if_index, subid, flags,
inner_vlan, outer_vlan, &phy_sw_if_index))
{
NL_ERROR ("link_add_vlan: cannot create sub-int on phy %U flags %u "
"inner-dot1q %u dot1%s %u",
format_vnet_sw_if_index_name, vnm, parent_sw->sup_sw_if_index,
flags, inner_vlan,
parent_sw->sub.eth.flags.dot1ad ? "ad" : "q", outer_vlan);
vlib_worker_thread_barrier_release (vlib_get_main ());
lcpm->lcp_auto_subint = old_lcp_auto_subint;
return NULL;
}
/* Try to use the same subid on the TAP, generate a unique one otherwise. */
if (vnet_sw_interface_subid_exists (vnm, phy_lip->lip_host_sw_if_index,
subid) &&
vnet_sw_interface_get_available_subid (
vnm, phy_lip->lip_host_sw_if_index, &subid))
{
NL_ERROR ("link_add_vlan: cannot find available subid on host %U",
format_vnet_sw_if_index_name, vnm,
phy_lip->lip_host_sw_if_index);
vlib_worker_thread_barrier_release (vlib_get_main ());
lcpm->lcp_auto_subint = old_lcp_auto_subint;
return NULL;
}
NL_NOTICE ("link_add_vlan: creating subid %u outer %u inner %u flags %u on "
"host %U phy %U",
subid, outer_vlan, inner_vlan, flags,
format_vnet_sw_if_index_name, vnm,
parent_lip->lip_host_sw_if_index, format_vnet_sw_if_index_name,
vnm, phy_lip->lip_host_sw_if_index);
if (vnet_create_sub_interface (phy_lip->lip_host_sw_if_index, subid, flags,
inner_vlan, outer_vlan, &host_sw_if_index))
{
NL_ERROR ("link_add_vlan: cannot create sub-int on host %U flags %u "
"inner-dot1q %u dot1%s %u",
format_vnet_sw_if_index_name, vnm,
phy_lip->lip_host_sw_if_index, flags, inner_vlan,
parent_sw->sub.eth.flags.dot1ad ? "ad" : "q", outer_vlan);
vlib_worker_thread_barrier_release (vlib_get_main ());
lcpm->lcp_auto_subint = old_lcp_auto_subint;
return NULL;
}
NL_NOTICE ("link_add_vlan: Creating LCP for host %U phy %U name %s idx %d",
format_vnet_sw_if_index_name, vnm, host_sw_if_index,
format_vnet_sw_if_index_name, vnm, phy_sw_if_index,
rtnl_link_get_name (rl), idx);
vlib_worker_thread_barrier_release (vlib_get_main ());
lcpm->lcp_auto_subint = old_lcp_auto_subint;
u8 *if_namev = 0;
char *if_name;
if_name = rtnl_link_get_name (rl);
vec_validate_init_c_string (if_namev, if_name, strnlen (if_name, IFNAMSIZ));
lcp_itf_pair_add (host_sw_if_index, phy_sw_if_index, if_namev, idx,
phy_lip->lip_host_type, phy_lip->lip_namespace);
vec_free (if_namev);
// If all went well, we just created a new LIP and added it to the index --
// so return that new (sub-interface) LIP to the caller.
return lcp_itf_pair_get (lcp_itf_pair_find_by_phy (phy_sw_if_index));
}
void
lcp_nl_link_del (struct rtnl_link *rl)
{
lcp_itf_pair_t *lip;
NL_DBG ("link_del: netlink %U", format_nl_object, rl);
if (!(lip = lcp_itf_pair_get (
lcp_itf_pair_find_by_vif (rtnl_link_get_ifindex (rl)))))
{
NL_WARN ("link_del: no LCP for %U ", format_nl_object, rl);
return;
}
NL_NOTICE ("link_del: Removing %U", format_lcp_itf_pair, lip);
vlib_worker_thread_barrier_sync (vlib_get_main ());
lcp_itf_pair_delete (lip->lip_phy_sw_if_index);
vlib_worker_thread_barrier_release (vlib_get_main ());
if (rtnl_link_is_vlan (rl))
{
NL_NOTICE ("link_del: Removing subint %U", format_vnet_sw_if_index_name,
vnet_get_main (), lip->lip_phy_sw_if_index);
vlib_worker_thread_barrier_sync (vlib_get_main ());
vnet_delete_sub_interface (lip->lip_phy_sw_if_index);
vnet_delete_sub_interface (lip->lip_host_sw_if_index);
vlib_worker_thread_barrier_release (vlib_get_main ());
}
return;
}
static void
lcp_nl_link_set_mtu (struct rtnl_link *rl, lcp_itf_pair_t *lip)
{
vnet_main_t *vnm = vnet_get_main ();
u32 mtu;
vnet_sw_interface_t *sw;
vnet_hw_interface_t *hw;
mtu = rtnl_link_get_mtu (rl);
if (!mtu)
return;
sw = vnet_get_sw_interface (vnm, lip->lip_phy_sw_if_index);
hw = vnet_get_sup_hw_interface (vnm, lip->lip_phy_sw_if_index);
if (!sw || !hw)
return;
/* Set the MTU on the TAP and sw */
vnet_sw_interface_set_mtu (vnm, lip->lip_host_sw_if_index, mtu);
vnet_sw_interface_set_mtu (vnm, lip->lip_phy_sw_if_index, mtu);
}
static void
lcp_nl_link_set_lladdr (struct rtnl_link *rl, lcp_itf_pair_t *lip)
{
vnet_main_t *vnm = vnet_get_main ();
struct nl_addr *mac_addr;
vnet_sw_interface_t *sw;
vnet_hw_interface_t *hw;
void *mac_addr_bytes;
mac_addr = rtnl_link_get_addr (rl);
if (!mac_addr || (nl_addr_get_family (mac_addr) != AF_LLC))
return;
sw = vnet_get_sw_interface (vnm, lip->lip_phy_sw_if_index);
hw = vnet_get_sup_hw_interface (vnm, lip->lip_phy_sw_if_index);
if (!sw || !hw)
return;
/* can only change address on hw interface */
if (sw->sw_if_index != sw->sup_sw_if_index)
return;
/* can only change if there's an address present */
if (!vec_len (hw->hw_address))
return;
mac_addr_bytes = nl_addr_get_binary_addr (mac_addr);
if (clib_memcmp (mac_addr_bytes, hw->hw_address, nl_addr_get_len (mac_addr)))
vnet_hw_interface_change_mac_address (vnm, hw->hw_if_index,
mac_addr_bytes);
/* mcast adjacencies need to be updated */
vnet_update_adjacency_for_sw_interface (vnm, lip->lip_phy_sw_if_index,
lip->lip_phy_adjs.adj_index[AF_IP4]);
vnet_update_adjacency_for_sw_interface (vnm, lip->lip_phy_sw_if_index,
lip->lip_phy_adjs.adj_index[AF_IP6]);
}
void
lcp_nl_link_add (struct rtnl_link *rl, void *ctx)
{
vnet_main_t *vnm = vnet_get_main ();
lcp_itf_pair_t *lip;
int admin_state;
NL_DBG ("link_add: netlink %U", format_nl_object, rl);
/* For NEWLINK messages, if this interface doesn't have a LIP, it
* may be a request to create a sub-int; so we call add_vlan()
* to create it and pass its new LIP so we can finish the request.
*/
if (!(lip = lcp_itf_pair_get (
lcp_itf_pair_find_by_vif (rtnl_link_get_ifindex (rl)))))
{
if (!(lip = lcp_nl_link_add_vlan (rl)))
return;
}
admin_state = (IFF_UP & rtnl_link_get_flags (rl));
vlib_worker_thread_barrier_sync (vlib_get_main ());
if (admin_state)
{
vnet_sw_interface_admin_up (vnm, lip->lip_host_sw_if_index);
vnet_sw_interface_admin_up (vnm, lip->lip_phy_sw_if_index);
}
else
{
vnet_sw_interface_admin_down (vnm, lip->lip_phy_sw_if_index);
vnet_sw_interface_admin_down (vnm, lip->lip_host_sw_if_index);
}
lcp_nl_link_set_mtu (rl, lip);
lcp_nl_link_set_lladdr (rl, lip);
vlib_worker_thread_barrier_release (vlib_get_main ());
NL_NOTICE ("link_add: %U admin %s", format_lcp_itf_pair, lip,
admin_state ? "up" : "down");
return;
}
static const mfib_prefix_t ip4_specials[] = {
/* ALL prefixes are in network order */
{
/* (*,224.0.0.0)/24 - all local subnet */
.fp_grp_addr = {
.ip4.data_u32 = 0x000000e0,
},
.fp_len = 24,
.fp_proto = FIB_PROTOCOL_IP4,
},
};
static void
lcp_nl_ip4_mroutes_add_del (u32 sw_if_index, u8 is_add)
{
const fib_route_path_t path = {
.frp_proto = DPO_PROTO_IP4,
.frp_addr = zero_addr,
.frp_sw_if_index = sw_if_index,
.frp_fib_index = ~0,
.frp_weight = 1,
.frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT,
};
u32 mfib_index;
int ii;
mfib_index =
mfib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, sw_if_index);
for (ii = 0; ii < ARRAY_LEN (ip4_specials); ii++)
{
if (is_add)
{
mfib_table_entry_path_update (mfib_index, &ip4_specials[ii],
MFIB_SOURCE_PLUGIN_LOW, &path);
}
else
{
mfib_table_entry_path_remove (mfib_index, &ip4_specials[ii],
MFIB_SOURCE_PLUGIN_LOW, &path);
}
}
}
static const mfib_prefix_t ip6_specials[] = {
/* ALL prefixes are in network order */
{
/* (*,ff00::)/8 - all local subnet */
.fp_grp_addr = {
.ip6.as_u64[0] = 0x00000000000000ff,
},
.fp_len = 8,
.fp_proto = FIB_PROTOCOL_IP6,
},
};
static void
lcp_nl_ip6_mroutes_add_del (u32 sw_if_index, u8 is_add)
{
const fib_route_path_t path = {
.frp_proto = DPO_PROTO_IP6,
.frp_addr = zero_addr,
.frp_sw_if_index = sw_if_index,
.frp_fib_index = ~0,
.frp_weight = 1,
.frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT,
};
u32 mfib_index;
int ii;
mfib_index =
mfib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP6, sw_if_index);
for (ii = 0; ii < ARRAY_LEN (ip6_specials); ii++)
{
if (is_add)
{
mfib_table_entry_path_update (mfib_index, &ip6_specials[ii],
MFIB_SOURCE_PLUGIN_LOW, &path);
}
else
{
mfib_table_entry_path_remove (mfib_index, &ip6_specials[ii],
MFIB_SOURCE_PLUGIN_LOW, &path);
}
}
}
static void
lcp_nl_addr_add_del (struct rtnl_addr *ra, int is_del)
{
lcp_itf_pair_t *lip;
ip_address_t nh;
NL_DBG ("addr_%s: netlink %U", is_del ? "del" : "add", format_nl_object, ra);
if (!(lip = lcp_itf_pair_get (
lcp_itf_pair_find_by_vif (rtnl_addr_get_ifindex (ra)))))
{
NL_WARN ("addr_%s: no LCP for %U ", is_del ? "del" : "add",
format_nl_object, ra);
return;
}
lcp_nl_mk_ip_addr (rtnl_addr_get_local (ra), &nh);
vlib_worker_thread_barrier_sync (vlib_get_main ());
if (AF_IP4 == ip_addr_version (&nh))
{
ip4_add_del_interface_address (
vlib_get_main (), lip->lip_phy_sw_if_index, &ip_addr_v4 (&nh),
rtnl_addr_get_prefixlen (ra), is_del);
lcp_nl_ip4_mroutes_add_del (lip->lip_phy_sw_if_index, !is_del);
}
else if (AF_IP6 == ip_addr_version (&nh))
{
if (ip6_address_is_link_local_unicast (&ip_addr_v6 (&nh)))
if (is_del)
ip6_link_disable (lip->lip_phy_sw_if_index);
else
{
ip6_link_enable (lip->lip_phy_sw_if_index, NULL);
ip6_link_set_local_address (lip->lip_phy_sw_if_index,
&ip_addr_v6 (&nh));
}
else
ip6_add_del_interface_address (
vlib_get_main (), lip->lip_phy_sw_if_index, &ip_addr_v6 (&nh),
rtnl_addr_get_prefixlen (ra), is_del);
lcp_nl_ip6_mroutes_add_del (lip->lip_phy_sw_if_index, !is_del);
}
vlib_worker_thread_barrier_release (vlib_get_main ());
NL_NOTICE ("addr_%s %U/%d iface %U", is_del ? "del: Deleted" : "add: Added",
format_ip_address, &nh, rtnl_addr_get_prefixlen (ra),
format_vnet_sw_if_index_name, vnet_get_main (),
lip->lip_phy_sw_if_index);
}
void
lcp_nl_addr_add (struct rtnl_addr *ra)
{
lcp_nl_addr_add_del (ra, 0);
}
void
lcp_nl_addr_del (struct rtnl_addr *ra)
{
lcp_nl_addr_add_del (ra, 1);
}
void
lcp_nl_neigh_add (struct rtnl_neigh *rn)
{
lcp_itf_pair_t *lip;
struct nl_addr *ll;
ip_address_t nh;
int state;
NL_DBG ("neigh_add: netlink %U", format_nl_object, rn);
if (!(lip = lcp_itf_pair_get (
lcp_itf_pair_find_by_vif (rtnl_neigh_get_ifindex (rn)))))
{
NL_WARN ("neigh_add: no LCP for %U ", format_nl_object, rn);
return;
}
lcp_nl_mk_ip_addr (rtnl_neigh_get_dst (rn), &nh);
ll = rtnl_neigh_get_lladdr (rn);
state = rtnl_neigh_get_state (rn);
if (ll && (state & NUD_VALID))
{
mac_address_t mac;
ip_neighbor_flags_t flags;
int rv;
lcp_nl_mk_mac_addr (ll, &mac);
if (state & (NUD_NOARP | NUD_PERMANENT))
flags = IP_NEIGHBOR_FLAG_STATIC;
else
flags = IP_NEIGHBOR_FLAG_DYNAMIC;
vlib_worker_thread_barrier_sync (vlib_get_main ());
rv = ip_neighbor_add (&nh, &mac, lip->lip_phy_sw_if_index, flags, NULL);
vlib_worker_thread_barrier_release (vlib_get_main ());
if (rv)
{
NL_ERROR ("neigh_add: Failed %U lladdr %U iface %U",
format_ip_address, &nh, format_mac_address, &mac,
format_vnet_sw_if_index_name, vnet_get_main (),
lip->lip_phy_sw_if_index);
}
else
{
NL_NOTICE ("neigh_add: Added %U lladdr %U iface %U",
format_ip_address, &nh, format_mac_address, &mac,
format_vnet_sw_if_index_name, vnet_get_main (),
lip->lip_phy_sw_if_index);
}
}
}
void
lcp_nl_neigh_del (struct rtnl_neigh *rn)
{
ip_address_t nh;
int rv;
NL_DBG ("neigh_del: netlink %U", format_nl_object, rn);
lcp_itf_pair_t *lip;
if (!(lip = lcp_itf_pair_get (
lcp_itf_pair_find_by_vif (rtnl_neigh_get_ifindex (rn)))))
{
NL_WARN ("neigh_del: no LCP for %U ", format_nl_object, rn);
return;
}
lcp_nl_mk_ip_addr (rtnl_neigh_get_dst (rn), &nh);
vlib_worker_thread_barrier_sync (vlib_get_main ());
rv = ip_neighbor_del (&nh, lip->lip_phy_sw_if_index);
vlib_worker_thread_barrier_release (vlib_get_main ());
if (rv == 0 || rv == VNET_API_ERROR_NO_SUCH_ENTRY)
{
NL_NOTICE ("neigh_del: Deleted %U iface %U", format_ip_address, &nh,
format_vnet_sw_if_index_name, vnet_get_main (),
lip->lip_phy_sw_if_index);
}
else
{
NL_ERROR ("neigh_del: Failed %U iface %U", format_ip_address, &nh,
format_vnet_sw_if_index_name, vnet_get_main (),
lip->lip_phy_sw_if_index);
}
}