20 #include <sys/socket.h> 24 #include <netlink/route/link/vlan.h> 63 #define LCP_ITF_PAIR_DBG(...) \ 64 vlib_log_notice (lcp_itf_pair_logger, __VA_ARGS__); 66 #define LCP_ITF_PAIR_INFO(...) \ 67 vlib_log_notice (lcp_itf_pair_logger, __VA_ARGS__); 77 s =
format (s,
"itf-pair: [%d]", lip - lcp_itf_pair_pool);
81 s =
format (s,
" <no-phy-if>");
87 s =
format (s,
" <no-host-if>");
126 ns ? (
char *) ns :
"<unset>");
128 if (phy_sw_if_index == ~0)
161 u32 phy_sw_if_index,
u8 *ns)
173 [
AF_IP4] =
"linux-cp-xc-ip4",
174 [
AF_IP6] =
"linux-cp-xc-ip6",
177 [
AF_IP4] =
"linux-cp-xc-l3-ip4",
178 [
AF_IP6] =
"linux-cp-xc-l3-ip6",
241 return VNET_API_ERROR_VALUE_EXIST;
332 struct rtnl_link *link;
336 sk = nl_socket_alloc ();
337 if ((err = nl_connect (sk, NETLINK_ROUTE)) < 0)
340 link = rtnl_link_vlan_alloc ();
342 rtnl_link_set_link (link, parent);
343 rtnl_link_set_name (link, name);
345 rtnl_link_vlan_set_id (link, vlan);
347 if ((err = rtnl_link_add (sk, link, NLM_F_CREATE)) < 0)
350 rtnl_link_put (link);
359 struct rtnl_link *link;
363 sk = nl_socket_alloc ();
364 if ((err = nl_connect (sk, NETLINK_ROUTE)) < 0)
367 link = rtnl_link_alloc ();
368 rtnl_link_set_name (link, name);
370 if ((err = rtnl_link_delete (sk, link)) < 0)
373 rtnl_link_put (link);
389 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
437 u32 host_sw_if_index;
467 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
503 host = phy = ns = default_ns = NULL;
509 if (
unformat (input,
"pair %s %s %s", &phy, &host, &ns))
516 "linux-cp IF namespace must" 517 " be less than %d characters",
527 else if (
unformat (input,
"pair %v %v", &phy, &host))
537 else if (
unformat (input,
"default netns %v", &default_ns))
543 "linux-cp default namespace must" 544 " be less than %d characters",
548 else if (
unformat (input,
"interface-auto-create"))
603 char ns_path[256] =
"/proc/self/ns/net";
606 snprintf (ns_path,
sizeof (ns_path) - 1,
"/var/run/netns/%s", ns_name);
608 return open (ns_path, O_RDONLY);
614 int curr_ns_fd, vif_ns_fd;
616 curr_ns_fd = vif_ns_fd = -1;
622 curr_ns_fd = open (
"/proc/self/ns/net", O_RDONLY);
623 ns_path =
format (0,
"/var/run/netns/%s%c", (
char *) ns, 0);
624 vif_ns_fd = open ((
char *) ns_path, O_RDONLY);
626 setns (vif_ns_fd, CLONE_NEWNET);
634 if (curr_ns_fd != -1)
636 setns (curr_ns_fd, CLONE_NEWNET);
644 u32 *host_sw_if_indexp)
648 u32 vif_index = 0, host_sw_if_index;
653 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
656 return VNET_API_ERROR_INVALID_ARGUMENT;
667 if (ns == 0 || ns[0] == 0)
674 int orig_ns_fd, ns_fd;
687 orig_ns_fd = ns_fd = -1;
690 if (ns && ns[0] != 0)
694 if (orig_ns_fd == -1 || ns_fd == -1)
697 setns (ns_fd, CLONE_NEWNET);
708 (
const char *) host_if_name);
710 if (!err && -1 != ns_fd)
729 if (orig_ns_fd != -1)
731 setns (orig_ns_fd, CLONE_NEWNET);
738 return VNET_API_ERROR_INVALID_ARGUMENT;
748 .host_if_name = host_if_name,
767 if (ns && ns[0] != 0)
819 lcp_itf_pair_add (host_sw_if_index, phy_sw_if_index, host_if_name, vif_index,
825 host_sw_if_index, host_if_name);
827 if (host_sw_if_indexp)
828 *host_sw_if_indexp = host_sw_if_index;
893 uword *event_data = 0;
906 lipn = &lipn_names[*lipn_index];
920 .name =
"linux-cp-itf-process",
979 if (flags & VNET_HW_INTERFACE_FLAG_LINK_UP)
1011 .runs_after =
VLIB_INITS (
"vnet_interface_init",
"tcp_init",
"udp_init"),
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
int lcp_itf_pair_replace_end(void)
lip_host_type_t lip_host_type
int lcp_itf_pair_del(u32 phy_sw_if_index)
const fib_route_path_flags_t lcp_itf_route_path_flags[N_LCP_ITF_HOST]
static walk_rc_t lcp_itf_pair_walk_show_cb(index_t api, void *ctx)
A path that resolves via a DVR DPO.
#define hash_set(h, key, value)
vnet_interface_output_runtime_t * rt
#define pool_foreach_index(i, v)
clib_error_t * vnet_netlink_set_link_state(int ifindex, int up)
static void lcp_itf_unset_adjs(lcp_itf_pair_t *lip)
vl_api_wireguard_peer_flags_t flags
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
A representation of a path as described by a route producer.
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
void ip4_punt_redirect_del(u32 rx_sw_if_index)
static f64 vlib_time_now(vlib_main_t *vm)
ethernet_interface_t * interfaces
static void lcp_itf_pair_delete_by_index(index_t lipi)
index_t lcp_itf_pair_find_by_vif(u32 vif_index)
Find a interface-pair object from the host interface.
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
int vlib_punt_hdl_t
Typedef for a client handle.
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
struct lcp_itf_pair_sweep_ctx_t_ lcp_itf_pair_sweep_ctx_t
static_always_inline void mac_address_copy(mac_address_t *dst, const mac_address_t *src)
int lcp_set_default_ns(u8 *ns)
Get/Set the default namespace for LCP host taps.
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
dpo_proto_t frp_proto
The protocol of the address below.
walk_rc_t(* lcp_itf_pair_walk_cb_t)(index_t index, void *ctx)
Callback function invoked during a walk of all interface-pairs.
void ip4_punt_redirect_add_paths(u32 rx_sw_if_index, fib_route_path_t *paths)
static uword vnet_sw_interface_is_sub(vnet_main_t *vnm, u32 sw_if_index)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
format_function_t format_vnet_sw_if_index_name
static index_t lcp_itf_pair_find_by_phy(u32 phy_sw_if_index)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
u8 * lcp_get_default_ns(void)
clib_error_t * vnet_netlink_set_link_netns(int ifindex, int netns_fd, char *new_ifname)
enum walk_rc_t_ walk_rc_t
Walk return code.
u32 lcp_itf_num_pairs(void)
ethernet_main_t ethernet_main
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
#define VLIB_INIT_FUNCTION(x)
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
description fragment has unexpected format
void vnet_sw_interface_admin_up(vnet_main_t *vnm, u32 sw_if_index)
int tap_delete_if(vlib_main_t *vm, u32 sw_if_index)
#define clib_error_return(e, args...)
vnet_main_t * vnet_get_main(void)
int vnet_create_sub_interface(u32 sw_if_index, u32 id, u32 flags, u16 inner_vlan_id, u16 outer_vlan_id, u32 *sub_sw_if_index)
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION(lcp_itf_pair_link_up_down)
enum fib_route_path_flags_t_ fib_route_path_flags_t
Path flags from the control plane.
static clib_error_t * lcp_itf_phy_add(vnet_main_t *vnm, u32 sw_if_index, u32 is_create)
int lcp_itf_pair_add(u32 host_sw_if_index, u32 phy_sw_if_index, u8 *host_name, u32 host_index, lip_host_type_t host_type, u8 *ns)
Create an interface-pair.
vlib_punt_hdl_t vlib_punt_client_register(const char *who)
Register a new clinet.
struct lcp_itf_pair_names_t_ lcp_itf_pair_names_t
description ARP replies copied to host
format_function_t format_vnet_sw_interface_name
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
vl_api_interface_index_t sw_if_index
lcp_itf_pair_t * lcp_itf_pair_pool
Pool of LIP objects.
static void lcp_itf_set_vif_link_state(u32 vif_index, u8 up, u8 *ns)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
int lcp_itf_pair_create(u32 phy_sw_if_index, u8 *host_if_name, lip_host_type_t host_if_type, u8 *ns, u32 *host_sw_if_indexp)
Create an interface-pair from PHY sw_if_index and tap name.
#define pool_put(P, E)
Free an object E in pool P.
#define vec_dup(V)
Return copy of vector (no header, no alignment)
static clib_error_t * lcp_itf_pair_link_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
#define ETHERNET_INTERFACE_FLAG_STATUS_L3
ethernet_interface_address_t address
static clib_error_t * lcp_netlink_del_link(const char *name)
static void lcp_itf_set_adjs(lcp_itf_pair_t *lip)
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
int lcp_itf_pair_delete(u32 phy_sw_if_index)
Delete a LCP_ITF_PAIR.
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
static int lcp_itf_get_ns_fd(char *ns_name)
static lcp_itf_pair_names_t * lipn_names
static walk_rc_t lcp_itf_pair_walk_mark(index_t lipi, void *ctx)
u8 * format_lcp_itf_pair(u8 *s, va_list *args)
void udp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
static walk_rc_t lcp_itf_pair_walk_sweep(index_t lipi, void *arg)
static uword vnet_sw_if_index_is_api_valid(u32 sw_if_index)
#define VLIB_EARLY_CONFIG_FUNCTION(x, n,...)
vlib_punt_reason_t ipsec_punt_reason[IPSEC_PUNT_N_REASONS]
#define VLIB_REGISTER_NODE(x,...)
static int lcp_validate_if_name(u8 *name)
#define LCP_ITF_PAIR_INFO(...)
static uword lcp_itf_pair_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
int vnet_delete_sub_interface(u32 sw_if_index)
static vlib_punt_hdl_t punt_hdl
#define vec_free(V)
Free vector's memory (no header).
static clib_error_t * lcp_itf_pair_init(vlib_main_t *vm)
VNET_SW_INTERFACE_ADD_DEL_FUNCTION(lcp_itf_phy_add)
void ip6_punt_redirect_del(u32 rx_sw_if_index)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
void ip6_punt_redirect_add_paths(u32 rx_sw_if_index, fib_route_path_t *paths)
static clib_error_t * lcp_itf_pair_config(vlib_main_t *vm, unformat_input_t *input)
lcp_itf_phy_adj_t lip_phy_adjs
fib_route_path_flags_t frp_flags
flags on the path
#define FOR_EACH_IP_ADDRESS_FAMILY(_af)
#define vec_cmp(v1, v2)
Compare two vectors (only applicable to vectors of signed numbers).
static uword * lip_db_by_vif
DBs of interface-pair objects:
unsigned int if_nametoindex(const char *ifname)
int lcp_itf_pair_add_sub(u32 vif, u8 *host_if_name, u32 sub_sw_if_index, u32 phy_sw_if_index, u8 *ns)
virtio_main_t virtio_main
static vlib_main_t * vlib_get_main(void)
void ip_feature_enable_disable(ip_address_family_t af, ip_sub_address_family_t safi, ip_feature_location_t loc, const char *feature_name, u32 sw_if_index, int enable, void *feature_config, u32 n_feature_config_bytes)
enum ip_address_family_t_ ip_address_family_t
void lcp_itf_pair_walk(lcp_itf_pair_walk_cb_t cb, void *ctx)
Walk/visit each of the interface pairs.
static vlib_node_registration_t lcp_itf_pair_process_node
(constructor) VLIB_REGISTER_NODE (lcp_itf_pair_process_node)
void tap_create_if(vlib_main_t *vm, tap_create_if_args_t *args)
void tcp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
int vlib_punt_register(vlib_punt_hdl_t client, vlib_punt_reason_t reason, const char *node_name)
Register a node to receive particular punted buffers.
void lcp_itf_pair_show(u32 phy_sw_if_index)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
adj_index_t adj_index[N_AF]
mac_address_t host_mac_addr
int tap_set_speed(u32 hw_if_index, u32 speed)
lcp_itf_pair_t * lcp_itf_pair_get(u32 index)
Get an interface-pair object from its VPP index.
int tap_set_carrier(u32 hw_if_index, u32 carrier_up)
#define clib_strnlen(s, m)
static vnet_hw_interface_t * vnet_get_hw_interface_or_null(vnet_main_t *vnm, u32 hw_if_index)
static u32 vlib_num_workers()
adj_index_t adj_mcast_add_or_lock(fib_protocol_t proto, vnet_link_t link_type, u32 sw_if_index)
Mcast Adjacency.
adj_index_t adj_nbr_add_or_lock(fib_protocol_t nh_proto, vnet_link_t link_type, const ip46_address_t *nh_addr, u32 sw_if_index)
Neighbour Adjacency sub-type.
#define vec_foreach(var, vec)
Vector iterator.
index_t * lip_db_by_phy
Retreive the pair in the DP.
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
import vnet interface_types api
int lcp_itf_pair_replace_begin(void)
Begin and End the replace process.
static clib_error_t * lcp_netlink_add_link_vlan(int parent, u32 vlan, const char *name)
static vnet_sw_interface_t * vnet_get_sw_interface_or_null(vnet_main_t *vnm, u32 sw_if_index)
void lcp_set_auto_intf(u8 is_auto)
manage interface auto creation
const ip46_address_t zero_addr
#include <vnet/feature/feature.h>
static vlib_log_class_t lcp_itf_pair_logger
const char * lcp_itf_l3_feat_names[N_LCP_ITF_HOST][N_AF]
struct vnet_sub_interface_t::@368 eth
int __clib_weak lcp_nl_drain_messages(void)
static uword pool_elts(void *v)
Number of active elements in a pool.