summaryrefslogtreecommitdiffstats
path: root/test/vpp_srv6.py
blob: b6dbc01420743978bcc6e5c244be506d90f77943 (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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
"""
  SRv6 LocalSIDs

  object abstractions for representing SRv6 localSIDs in VPP
"""

from vpp_object import VppObject
from socket import inet_pton, inet_ntop, AF_INET, AF_INET6


class SRv6LocalSIDBehaviors():
    # from src/vnet/srv6/sr.h
    SR_BEHAVIOR_END = 1
    SR_BEHAVIOR_X = 2
    SR_BEHAVIOR_T = 3
    SR_BEHAVIOR_D_FIRST = 4   # Unused. Separator in between regular and D
    SR_BEHAVIOR_DX2 = 5
    SR_BEHAVIOR_DX6 = 6
    SR_BEHAVIOR_DX4 = 7
    SR_BEHAVIOR_DT6 = 8
    SR_BEHAVIOR_DT4 = 9
    SR_BEHAVIOR_LAST = 10      # Must always be the last one


class SRv6PolicyType():
    # from src/vnet/srv6/sr.h
    SR_POLICY_TYPE_DEFAULT = 0
    SR_POLICY_TYPE_SPRAY = 1


class SRv6PolicySteeringTypes():
    # from src/vnet/srv6/sr.h
    SR_STEER_L2 = 2
    SR_STEER_IPV4 = 4
    SR_STEER_IPV6 = 6


class VppSRv6LocalSID(VppObject):
    """
    SRv6 LocalSID
    """

    def __init__(self, test, localsid, behavior, nh_addr4, nh_addr6,
                 end_psp, sw_if_index, vlan_index, fib_table):
        self._test = test
        self.localsid = localsid
        # keep binary format in _localsid
        self.localsid["addr"] = inet_pton(AF_INET6, self.localsid["addr"])
        self.behavior = behavior
        self.nh_addr4 = inet_pton(AF_INET, nh_addr4)
        self.nh_addr6 = inet_pton(AF_INET6, nh_addr6)
        self.end_psp = end_psp
        self.sw_if_index = sw_if_index
        self.vlan_index = vlan_index
        self.fib_table = fib_table
        self._configured = False

    def add_vpp_config(self):
        self._test.vapi.sr_localsid_add_del(
            self.localsid,
            self.behavior,
            self.nh_addr4,
            self.nh_addr6,
            is_del=0,
            end_psp=self.end_psp,
            sw_if_index=self.sw_if_index,
            vlan_index=self.vlan_index,
            fib_table=self.fib_table)
        self._configured = True

    def remove_vpp_config(self):
        self._test.vapi.sr_localsid_add_del(
            self.localsid,
            self.behavior,
            self.nh_addr4,
            self.nh_addr6,
            is_del=1,
            end_psp=self.end_psp,
            sw_if_index=self.sw_if_index,
            vlan_index=self.vlan_index,
            fib_table=self.fib_table)
        self._configured = False

    def query_vpp_config(self):
        # sr_localsids_dump API is disabled
        # use _configured flag for now
        return self._configured

    def object_id(self):
        return ("%d;%s,%d"
                % (self.fib_table,
                   self.localsid,
                   self.behavior))


class VppSRv6Policy(VppObject):
    """
    SRv6 Policy
    """

    def __init__(self, test, bsid,
                 is_encap, sr_type, weight, fib_table,
                 segments, source):
        self._test = test
        self.bsid = bsid
        # keep binary format in _bsid
        self._bsid = inet_pton(AF_INET6, bsid)
        self.is_encap = is_encap
        self.sr_type = sr_type
        self.weight = weight
        self.fib_table = fib_table
        self.segments = segments
        # keep binary format in _segments
        self._segments = []
        for seg in segments:
            self._segments.extend(inet_pton(AF_INET6, seg))
        self.n_segments = len(segments)
        # source not passed to API
        # self.source = inet_pton(AF_INET6, source)
        self.source = source
        self._configured = False

    def add_vpp_config(self):
        self._test.vapi.sr_policy_add(
                     self._bsid,
                     self.weight,
                     self.is_encap,
                     self.sr_type,
                     self.fib_table,
                     self.n_segments,
                     self._segments)
        self._configured = True

    def remove_vpp_config(self):
        self._test.vapi.sr_policy_del(
                     self._bsid)
        self._configured = False

    def query_vpp_config(self):
        # no API to query SR Policies
        # use _configured flag for now
        return self._configured

    def object_id(self):
        return ("%d;%s-><%s>;%d"
                % (self.sr_type,
                   self.bsid,
                   ','.join(self.segments),
                   self.is_encap))


class VppSRv6Steering(VppObject):
    """
    SRv6 Steering
    """

    def __init__(self, test,
                 bsid,
                 prefix,
                 mask_width,
                 traffic_type,
                 sr_policy_index,
                 table_id,
                 sw_if_index):
        self._test = test
        self.bsid = bsid
        # keep binary format in _bsid
        self._bsid = inet_pton(AF_INET6, bsid)
        self.prefix = prefix
        # keep binary format in _prefix
        if ':' in prefix:
            # IPv6
            self._prefix = inet_pton(AF_INET6, prefix)
        else:
            # IPv4
            # API expects 16 octets (128 bits)
            # last 4 octets are used for IPv4
            # --> prepend 12 octets
            self._prefix = ('\x00' * 12) + inet_pton(AF_INET, prefix)
        self.mask_width = mask_width
        self.traffic_type = traffic_type
        self.sr_policy_index = sr_policy_index
        self.sw_if_index = sw_if_index
        self.table_id = table_id
        self._configured = False

    def add_vpp_config(self):
        self._test.vapi.sr_steering_add_del(
                     0,
                     self._bsid,
                     self.sr_policy_index,
                     self.table_id,
                     self._prefix,
                     self.mask_width,
                     self.sw_if_index,
                     self.traffic_type)
        self._configured = True

    def remove_vpp_config(self):
        self._test.vapi.sr_steering_add_del(
                     1,
                     self._bsid,
                     self.sr_policy_index,
                     self.table_id,
                     self._prefix,
                     self.mask_width,
                     self.sw_if_index,
                     self.traffic_type)
        self._configured = False

    def query_vpp_config(self):
        # no API to query steering entries
        # use _configured flag for now
        return self._configured

    def object_id(self):
        return ("%d;%d;%s/%d->%s"
                % (self.table_id,
                   self.traffic_type,
                   self.prefix,
                   self.mask_width,
                   self.bsid))
pan class="n">q, p, copy_size); clib_mem_free (p); } return q; } always_inline uword clib_mem_size (void *p) { #if USE_DLMALLOC == 0 mheap_elt_t *e = mheap_user_pointer_to_elt (p); ASSERT (clib_mem_is_heap_object (p)); return mheap_elt_data_bytes (e); #else ASSERT (clib_mem_is_heap_object (p)); return mspace_usable_size_with_delta (p); #endif } always_inline void * clib_mem_get_heap (void) { return clib_mem_get_per_cpu_heap (); } always_inline void * clib_mem_set_heap (void *heap) { return clib_mem_set_per_cpu_heap (heap); } void *clib_mem_init (void *heap, uword size); void *clib_mem_init_thread_safe (void *memory, uword memory_size); void clib_mem_exit (void); uword clib_mem_get_page_size (void); void clib_mem_validate (void); void clib_mem_trace (int enable); typedef struct { /* Total number of objects allocated. */ uword object_count; /* Total allocated bytes. Bytes used and free. used + free = total */ uword bytes_total, bytes_used, bytes_free; /* Number of bytes used by mheap data structure overhead (e.g. free lists, mheap header). */ uword bytes_overhead; /* Amount of free space returned to operating system. */ uword bytes_free_reclaimed; /* For malloc which puts small objects in sbrk region and large objects in mmap'ed regions. */ uword bytes_used_sbrk; uword bytes_used_mmap; /* Max. number of bytes in this heap. */ uword bytes_max; } clib_mem_usage_t; void clib_mem_usage (clib_mem_usage_t * usage); u8 *format_clib_mem_usage (u8 * s, va_list * args); /* Allocate virtual address space. */ always_inline void * clib_mem_vm_alloc (uword size) { void *mmap_addr; uword flags = MAP_PRIVATE; #ifdef MAP_ANONYMOUS flags |= MAP_ANONYMOUS; #endif mmap_addr = mmap (0, size, PROT_READ | PROT_WRITE, flags, -1, 0); if (mmap_addr == (void *) -1) mmap_addr = 0; return mmap_addr; } always_inline void clib_mem_vm_free (void *addr, uword size) { munmap (addr, size); } always_inline void * clib_mem_vm_unmap (void *addr, uword size) { void *mmap_addr; uword flags = MAP_PRIVATE | MAP_FIXED; /* To unmap we "map" with no protection. If we actually called munmap then other callers could steal the address space. By changing to PROT_NONE the kernel can free up the pages which is really what we want "unmap" to mean. */ mmap_addr = mmap (addr, size, PROT_NONE, flags, -1, 0); if (mmap_addr == (void *) -1) mmap_addr = 0; return mmap_addr; } always_inline void * clib_mem_vm_map (void *addr, uword size) { void *mmap_addr; uword flags = MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS; mmap_addr = mmap (addr, size, (PROT_READ | PROT_WRITE), flags, -1, 0); if (mmap_addr == (void *) -1) mmap_addr = 0; return mmap_addr; } typedef struct { #define CLIB_MEM_VM_F_SHARED (1 << 0) #define CLIB_MEM_VM_F_HUGETLB (1 << 1) #define CLIB_MEM_VM_F_NUMA_PREFER (1 << 2) #define CLIB_MEM_VM_F_NUMA_FORCE (1 << 3) #define CLIB_MEM_VM_F_HUGETLB_PREALLOC (1 << 4) #define CLIB_MEM_VM_F_LOCKED (1 << 5) u32 flags; /**< vm allocation flags: <br> CLIB_MEM_VM_F_SHARED: request shared memory, file descriptor will be provided on successful allocation. <br> CLIB_MEM_VM_F_HUGETLB: request hugepages. <br> CLIB_MEM_VM_F_NUMA_PREFER: numa_node field contains valid numa node preference. <br> CLIB_MEM_VM_F_NUMA_FORCE: fail if setting numa policy fails. <br> CLIB_MEM_VM_F_HUGETLB_PREALLOC: pre-allocate hugepages if number of available pages is not sufficient. <br> CLIB_MEM_VM_F_LOCKED: request locked memory. */ char *name; /**< Name for memory allocation, set by caller. */ uword size; /**< Allocation size, set by caller. */ int numa_node; /**< numa node preference. Valid if CLIB_MEM_VM_F_NUMA_PREFER set. */ void *addr; /**< Pointer to allocated memory, set on successful allocation. */ int fd; /**< File descriptor, set on successful allocation if CLIB_MEM_VM_F_SHARED is set. */ int log2_page_size; /* Page size in log2 format, set on successful allocation. */ int n_pages; /* Number of pages. */ uword requested_va; /**< Request fixed position mapping */ } clib_mem_vm_alloc_t; clib_error_t *clib_mem_create_hugetlb_fd (char *name, int *fdp); clib_error_t *clib_mem_vm_ext_alloc (clib_mem_vm_alloc_t * a); void clib_mem_vm_ext_free (clib_mem_vm_alloc_t * a); u64 clib_mem_vm_get_page_size (int fd); int clib_mem_vm_get_log2_page_size (int fd); u64 *clib_mem_vm_get_paddr (void *mem, int log2_page_size, int n_pages); typedef struct { uword size; /**< Map size */ int fd; /**< File descriptor to be mapped */ uword requested_va; /**< Request fixed position mapping */ void *addr; /**< Pointer to mapped memory, if successful */ } clib_mem_vm_map_t; clib_error_t *clib_mem_vm_ext_map (clib_mem_vm_map_t * a); void clib_mem_vm_randomize_va (uword * requested_va, u32 log2_page_size); void mheap_trace (void *v, int enable); #include <vppinfra/error.h> /* clib_panic */ #endif /* _included_clib_mem_h */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */