aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ip/ip6_ll_table.h
blob: 0667cf9912809db5b3df5a72457265b4ef7a51c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
 * Copyright (c) 2018 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.
 */

#ifndef __IP6_LL_TABLE_H__
#define __IP6_LL_TABLE_H__

#include <vnet/ip/ip.h>

#include <vnet/ip/ip6_ll_types.h>

/**
 * @brief
 *   A protocol Independent IP multicast FIB table
 */
typedef struct ip6_ll_table_t_
{
  /**
   * A vector, indexed by sw_if_index, of unicast IPv6 FIBs
   */
  u32 *ilt_fibs;

  /**
   * Total route counters
   */
  u32 ilt_total_route_counts;

} ip6_ll_table_t;

/**
 * @brief
 *  Perfom a longest prefix match in the non-forwarding table
 *
 * @param prefix
 *  The prefix to lookup
 *
 * @return
 *  The index of the fib_entry_t for the best match, which may be the default route
 */
extern fib_node_index_t ip6_ll_table_lookup (const ip6_ll_prefix_t * prefix);

/**
 * @brief
 *  Perfom an exact match in the non-forwarding table
 *
 * @param prefix
 *  The prefix to lookup
 *
 * @return
 *  The index of the fib_entry_t for the exact match, or INVALID
 *  is there is no match.
 */
extern fib_node_index_t ip6_ll_table_lookup_exact_match
  (const ip6_ll_prefix_t * prefix);

/**
 * @brief
 * Update an entry in the table. The falgs determine if the entry is
 * LOCAL, in which case it's a receive, or not, in which case the entry
 * will link to an adjacency.
 *
 * @param prefix
 *  The prefix for the entry to add
 *
 * @return
 *  the index of the fib_entry_t that is created (or existed already).
 */
extern fib_node_index_t ip6_ll_table_entry_update
  (const ip6_ll_prefix_t * prefix, fib_route_path_flags_t flags);

/**
 * @brief
 *  Delete a IP6 link-local entry.
 *
 * @param prefix
 *  The prefix for the entry to remove
 */
extern void ip6_ll_table_entry_delete (const ip6_ll_prefix_t * prefix);

/**
 * @brief For use in the data plane. Get the underlying ip6 FIB
 */
extern u32 ip6_ll_fib_get (u32 sw_if_index);

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */

#endif
p">): return self._tag1 @property def tag2(self): return self._tag2 @property def vtr(self): return self._vtr def __init__(self, test, parent, sub_id): VppInterface.__init__(self, test) self._parent = parent self._parent.add_sub_if(self) self._sub_id = sub_id self.DOT1AD_TYPE = 0x88A8 self.DOT1Q_TYPE = 0x8100 def set_sw_if_index(self, sw_if_index): super(VppSubInterface, self).set_sw_if_index(sw_if_index) self.set_vtr(L2_VTR_OP.L2_DISABLED) @abc.abstractmethod def create_arp_req(self): pass @abc.abstractmethod def create_ndp_req(self): pass def resolve_arp(self): super(VppSubInterface, self).resolve_arp(self.parent) def resolve_ndp(self): super(VppSubInterface, self).resolve_ndp(self.parent) @abc.abstractmethod def add_dot1_layer(self, pkt): pass def remove_vpp_config(self): self.test.vapi.delete_subif(self.sw_if_index) def _add_tag(self, packet, vlan, tag_type): payload = packet.payload inner_type = packet.type packet.remove_payload() packet.add_payload(Dot1Q(vlan=vlan) / payload) packet.payload.type = inner_type packet.payload.vlan = vlan packet.type = tag_type return packet def _remove_tag(self, packet, vlan=None, tag_type=None): if tag_type: self.test.instance().assertEqual(packet.type, tag_type) payload = packet.payload if vlan: self.test.instance().assertEqual(payload.vlan, vlan) inner_type = payload.type payload = payload.payload packet.remove_payload() packet.add_payload(payload) packet.type = inner_type return packet def add_dot1q_layer(self, packet, vlan): return self._add_tag(packet, vlan, self.DOT1Q_TYPE) def add_dot1ad_layer(self, packet, outer, inner): p = self._add_tag(packet, inner, self.DOT1Q_TYPE) return self._add_tag(p, outer, self.DOT1AD_TYPE) def remove_dot1q_layer(self, packet, vlan=None): return self._remove_tag(packet, vlan, self.DOT1Q_TYPE) def remove_dot1ad_layer(self, packet, outer=None, inner=None): p = self._remove_tag(packet, outer, self.DOT1AD_TYPE) return self._remove_tag(p, inner, self.DOT1Q_TYPE) def set_vtr(self, vtr, push1q=0, tag=None, inner=None, outer=None): self._tag1 = 0 self._tag2 = 0 self._push1q = 0 if (vtr == L2_VTR_OP.L2_PUSH_1 or vtr == L2_VTR_OP.L2_TRANSLATE_1_1 or vtr == L2_VTR_OP.L2_TRANSLATE_2_1): self._tag1 = tag self._push1q = push1q if (vtr == L2_VTR_OP.L2_PUSH_2 or vtr == L2_VTR_OP.L2_TRANSLATE_1_2 or vtr == L2_VTR_OP.L2_TRANSLATE_2_2): self._tag1 = outer self._tag2 = inner self._push1q = push1q self.test.vapi.l2_interface_vlan_tag_rewrite( sw_if_index=self.sw_if_index, vtr_op=vtr, push_dot1q=self._push1q, tag1=self._tag1, tag2=self._tag2) self._vtr = vtr class VppDot1QSubint(VppSubInterface): @property def vlan(self): """VLAN tag""" return self._vlan def __init__(self, test, parent, sub_id, vlan=None): super(VppDot1QSubint, self).__init__(test, parent, sub_id) if vlan is None: vlan = sub_id self._vlan = vlan r = test.vapi.create_vlan_subif(parent.sw_if_index, vlan) self.set_sw_if_index(r.sw_if_index) def create_arp_req(self): packet = VppPGInterface.create_arp_req(self) return self.add_dot1_layer(packet) def create_ndp_req(self): packet = VppPGInterface.create_ndp_req(self) return self.add_dot1_layer(packet) # called before sending packet def add_dot1_layer(self, packet): return self.add_dot1q_layer(packet, self.vlan) # called on received packet to "reverse" the add call def remove_dot1_layer(self, packet): return self.remove_dot1q_layer(packet, self.vlan) class VppDot1ADSubint(VppSubInterface): @property def outer_vlan(self): """Outer VLAN tag""" return self._outer_vlan @property def inner_vlan(self): """Inner VLAN tag""" return self._inner_vlan def __init__(self, test, parent, sub_id, outer_vlan, inner_vlan): super(VppDot1ADSubint, self).__init__(test, parent, sub_id) r = test.vapi.create_subif(sw_if_index=parent.sw_if_index, sub_id=sub_id, outer_vlan_id=outer_vlan, inner_vlan_id=inner_vlan, two_tags=1, dot1ad=1, exact_match=1) self.set_sw_if_index(r.sw_if_index) self._outer_vlan = outer_vlan self._inner_vlan = inner_vlan def create_arp_req(self): packet = VppPGInterface.create_arp_req(self) return self.add_dot1_layer(packet) def create_ndp_req(self): packet = VppPGInterface.create_ndp_req(self) return self.add_dot1_layer(packet) def add_dot1_layer(self, packet): return self.add_dot1ad_layer(packet, self.outer_vlan, self.inner_vlan) def remove_dot1_layer(self, packet): return self.remove_dot1ad_layer(packet, self.outer_vlan, self.inner_vlan) class VppP2PSubint(VppSubInterface): def __init__(self, test, parent, sub_id, remote_mac): super(VppP2PSubint, self).__init__(test, parent, sub_id) r = test.vapi.p2p_ethernet_add(parent.sw_if_index, remote_mac, sub_id) self.set_sw_if_index(r.sw_if_index) self.parent_sw_if_index = parent.sw_if_index self.p2p_remote_mac = remote_mac def add_dot1_layer(self, packet): return packet def remove_dot1_layer(self, packet): return packet def create_arp_req(self): packet = VppPGInterface.create_arp_req(self) return packet def create_ndp_req(self): packet = VppPGInterface.create_ndp_req(self) return packet