aboutsummaryrefslogtreecommitdiffstats
path: root/src/vlib/punt.c
AgeCommit message (Expand)AuthorFilesLines
2021-03-14ip: extend punt CLI for exception packetsMohammed Hawari1-8/+57
2020-05-15ikev2: add support for NAT traversalFilip Tehlar1-5/+6
2020-02-25vlib: Punt reason allocation listener enable/disable callbackNeale Ranns1-3/+31
2019-05-28Punt: socket register for exception dispatched/punted packets based on reasonNeale Ranns1-0/+20
2019-04-08vlib-punt: fix error node countingNeale Ranns1-1/+1
2019-03-28Punt InfraNeale Ranns1-0/+629
>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 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
"""
  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
import copy


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_END_UN_PERF = 10
    SR_BEHAVIOR_END_UN = 11
    SR_BEHAVIOR_LAST = 12  # Must always be the last one


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


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_addr,
        end_psp,
        sw_if_index,
        vlan_index,
        fib_table,
    ):
        self._test = test
        self.localsid = localsid
        self.behavior = behavior
        self.nh_addr = nh_addr
        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(
            localsid=self.localsid,
            behavior=self.behavior,
            nh_addr=self.nh_addr,
            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(
            localsid=self.localsid,
            behavior=self.behavior,
            nh_addr=self.nh_addr,
            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
        self.is_encap = is_encap
        self.sr_type = sr_type
        self.weight = weight
        self.fib_table = fib_table
        self.segments = segments
        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(
            bsid=self.bsid,
            weight=self.weight,
            is_encap=self.is_encap,
            is_spray=self.sr_type,
            fib_table=self.fib_table,
            sids={"num_sids": self.n_segments, "sids": 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 VppSRv6PolicyV2(VppObject):
    """
    SRv6 Policy
    """

    def __init__(
        self,
        test,
        bsid,
        is_encap,
        sr_type,
        weight,
        fib_table,
        segments,
        encap_src,
        source,
    ):
        self._test = test
        self.bsid = bsid
        self.is_encap = is_encap
        self.sr_type = sr_type
        self.weight = weight
        self.fib_table = fib_table
        self.segments = segments
        self.encap_src = encap_src
        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_v2(
            bsid_addr=self.bsid,
            weight=self.weight,
            is_encap=self.is_encap,
            type=self.sr_type,
            fib_table=self.fib_table,
            encap_src=self.encap_src,
            sids={
                "num_sids": self.n_segments,
                "sids": self._get_fixed_segments(),
                "weight": 1,
            },
        )
        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,
        )

    def _get_fixed_segments(self):
        segs = copy.copy(self.segments)
        # note: array expect size is 16
        for _ in range(16 - self.n_segments):
            segs.append("")
        return segs


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
        self.prefix = 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(
            is_del=0,
            bsid_addr=self.bsid,
            sr_policy_index=self.sr_policy_index,
            table_id=self.table_id,
            prefix={"address": self.prefix, "len": self.mask_width},
            sw_if_index=self.sw_if_index,
            traffic_type=self.traffic_type,
        )
        self._configured = True

    def remove_vpp_config(self):
        self._test.vapi.sr_steering_add_del(
            is_del=1,
            bsid_addr=self.bsid,
            sr_policy_index=self.sr_policy_index,
            table_id=self.table_id,
            prefix={"address": self.prefix, "len": self.mask_width},
            sw_if_index=self.sw_if_index,
            traffic_type=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,
        )