ifstate 1.13.0__tar.gz → 1.13.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ifstate-1.13.0 → ifstate-1.13.2}/PKG-INFO +1 -1
- {ifstate-1.13.0 → ifstate-1.13.2}/ifstate.egg-info/PKG-INFO +1 -1
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/__init__.py +5 -2
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/fdb/__init__.py +37 -31
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/link/base.py +26 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/routing/__init__.py +24 -2
- {ifstate-1.13.0 → ifstate-1.13.2}/schema/ifstate.conf.schema.json +44 -11
- {ifstate-1.13.0 → ifstate-1.13.2}/LICENSE +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/README.md +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/ifstate/__init__.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/ifstate/ifstate.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/ifstate/shell.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/ifstate/vrrp.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/ifstate.egg-info/SOURCES.txt +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/ifstate.egg-info/dependency_links.txt +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/ifstate.egg-info/entry_points.txt +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/ifstate.egg-info/requires.txt +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/ifstate.egg-info/top_level.txt +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/address/__init__.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/bpf/__init__.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/bpf/ctypes.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/bpf/map.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/brport/__init__.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/exception.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/link/__init__.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/link/dsa.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/link/physical.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/link/tun.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/link/veth.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/log.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/neighbour/__init__.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/netns/__init__.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/parser/__init__.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/parser/base.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/parser/yaml.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/sysctl/__init__.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/tc/__init__.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/util.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/wireguard/__init__.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/xdp/__init__.py +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/setup.cfg +0 -0
- {ifstate-1.13.0 → ifstate-1.13.2}/setup.py +0 -0
@@ -48,7 +48,7 @@ import json
|
|
48
48
|
import errno
|
49
49
|
import logging
|
50
50
|
|
51
|
-
__version__ = "1.13.
|
51
|
+
__version__ = "1.13.2"
|
52
52
|
|
53
53
|
|
54
54
|
class IfState():
|
@@ -111,6 +111,9 @@ class IfState():
|
|
111
111
|
self.ipaddr_ignore = set()
|
112
112
|
for ip in self.ignore.get('ipaddr', []):
|
113
113
|
self.ipaddr_ignore.add(ip_network(ip))
|
114
|
+
self.fdb_ignore = None
|
115
|
+
if self.ignore.get('fdb'):
|
116
|
+
self.fdb_ignore = re.compile('|'.join(self.ignore.get('fdb')))
|
114
117
|
|
115
118
|
# save cshaper profiles
|
116
119
|
self.cshaper_profiles = ifstates['cshaper']
|
@@ -598,7 +601,7 @@ class IfState():
|
|
598
601
|
'ipaddr_dynamic', True), do_apply)
|
599
602
|
|
600
603
|
if ifname in netns.fdb:
|
601
|
-
netns.fdb[ifname].apply(do_apply)
|
604
|
+
netns.fdb[ifname].apply(self.fdb_ignore, do_apply)
|
602
605
|
|
603
606
|
if ifname in netns.neighbours:
|
604
607
|
netns.neighbours[ifname].apply(do_apply)
|
@@ -88,7 +88,7 @@ class FDB():
|
|
88
88
|
|
89
89
|
return fdb
|
90
90
|
|
91
|
-
def apply(self, do_apply):
|
91
|
+
def apply(self, fdb_ignore_re, do_apply):
|
92
92
|
logger.debug('getting fdb', extra={'iface': self.iface})
|
93
93
|
|
94
94
|
# get ifindex and lladdr
|
@@ -108,41 +108,12 @@ class FDB():
|
|
108
108
|
if linkinfo and linkinfo.get_attr('IFLA_INFO_KIND') in ['vxlan']:
|
109
109
|
default_state |= NUD_NOARP
|
110
110
|
|
111
|
-
#
|
112
|
-
ipr_entries = self.get_kernel_fdb()
|
111
|
+
# set default_state if missing
|
113
112
|
for lladdr, entries in self.fdb.items():
|
114
113
|
for entry in entries:
|
115
|
-
# set default_state if missing
|
116
114
|
if not 'state' in entry:
|
117
115
|
entry['state'] = default_state
|
118
116
|
|
119
|
-
# check if fdb entry is already present
|
120
|
-
if lladdr in ipr_entries:
|
121
|
-
if entry in ipr_entries[lladdr]:
|
122
|
-
logger.log_ok('fdb', '= {}'.format(lladdr))
|
123
|
-
continue
|
124
|
-
|
125
|
-
# fdb entry needs to be added
|
126
|
-
logger.log_add('fdb', '+ {}'.format(lladdr))
|
127
|
-
|
128
|
-
# prepare arguments
|
129
|
-
args = {
|
130
|
-
'ifindex': self.idx,
|
131
|
-
'family': AF_BRIDGE
|
132
|
-
}
|
133
|
-
args.update(entry)
|
134
|
-
logger.debug("bridge fdb append: {}".format(
|
135
|
-
" ".join("{}={}".format(k, v) for k, v in args.items())))
|
136
|
-
|
137
|
-
if do_apply:
|
138
|
-
try:
|
139
|
-
self.netns.ipr.fdb("append", **args)
|
140
|
-
except Exception as err:
|
141
|
-
if not isinstance(err, netlinkerror_classes):
|
142
|
-
raise
|
143
|
-
logger.warning('add {} to fdb failed: {}'.format(
|
144
|
-
entry['lladdr'], err.args[1]))
|
145
|
-
|
146
117
|
# cleanup orphan fdb entries
|
147
118
|
ipr_entries = self.get_kernel_fdb()
|
148
119
|
for lladdr, entries in ipr_entries.items():
|
@@ -150,6 +121,10 @@ class FDB():
|
|
150
121
|
if lladdr == self.lladdr:
|
151
122
|
continue
|
152
123
|
|
124
|
+
# skip ignored lladdr
|
125
|
+
if fdb_ignore_re is not None and fdb_ignore_re.match(lladdr):
|
126
|
+
continue
|
127
|
+
|
153
128
|
for entry in entries:
|
154
129
|
# check if fdb entry is already present
|
155
130
|
if lladdr not in self.fdb or entry not in self.fdb[lladdr]:
|
@@ -172,3 +147,34 @@ class FDB():
|
|
172
147
|
raise
|
173
148
|
logger.warning('remove {} from fdb failed: {}'.format(
|
174
149
|
entry['lladdr'], err.args[1]))
|
150
|
+
|
151
|
+
# configure fdb entries
|
152
|
+
ipr_entries = self.get_kernel_fdb()
|
153
|
+
for lladdr, entries in self.fdb.items():
|
154
|
+
for entry in entries:
|
155
|
+
# check if fdb entry is already present
|
156
|
+
if lladdr in ipr_entries:
|
157
|
+
if entry in ipr_entries[lladdr]:
|
158
|
+
logger.log_ok('fdb', '= {}'.format(lladdr))
|
159
|
+
continue
|
160
|
+
|
161
|
+
# fdb entry needs to be added
|
162
|
+
logger.log_add('fdb', '+ {}'.format(lladdr))
|
163
|
+
|
164
|
+
# prepare arguments
|
165
|
+
args = {
|
166
|
+
'ifindex': self.idx,
|
167
|
+
'family': AF_BRIDGE
|
168
|
+
}
|
169
|
+
args.update(entry)
|
170
|
+
logger.debug("bridge fdb append: {}".format(
|
171
|
+
" ".join("{}={}".format(k, v) for k, v in args.items())))
|
172
|
+
|
173
|
+
if do_apply:
|
174
|
+
try:
|
175
|
+
self.netns.ipr.fdb("append", **args)
|
176
|
+
except Exception as err:
|
177
|
+
if not isinstance(err, netlinkerror_classes):
|
178
|
+
raise
|
179
|
+
logger.warning('add {} to fdb failed: {}'.format(
|
180
|
+
entry['lladdr'], err.args[1]))
|
@@ -66,6 +66,11 @@ class Link(ABC):
|
|
66
66
|
1: "bandwidth",
|
67
67
|
2: "count",
|
68
68
|
},
|
69
|
+
# === bridge ===
|
70
|
+
'br_vlan_protocol': {
|
71
|
+
0x88a8: '802.1ad',
|
72
|
+
0x8100: '802.1q',
|
73
|
+
},
|
69
74
|
# === tuntap ===
|
70
75
|
'tun_type': {
|
71
76
|
1: 'tun',
|
@@ -85,6 +90,7 @@ class Link(ABC):
|
|
85
90
|
}
|
86
91
|
attr_value_lookup = {
|
87
92
|
'group': RTLookups.group,
|
93
|
+
'vrf_table': RTLookups.tables,
|
88
94
|
}
|
89
95
|
attr_bind_kinds = [
|
90
96
|
'ip6tnl',
|
@@ -103,6 +109,12 @@ class Link(ABC):
|
|
103
109
|
'wireguard',
|
104
110
|
'xfrm',
|
105
111
|
]
|
112
|
+
# the attributes will be unset using an emptry string,
|
113
|
+
# if unset they are not return via netlink and handled
|
114
|
+
# as a `None` value in ifstate
|
115
|
+
attr_empty_unset = [
|
116
|
+
'ifalias',
|
117
|
+
]
|
106
118
|
|
107
119
|
def __new__(cls, *args, **kwargs):
|
108
120
|
cname = cls.__name__
|
@@ -207,6 +219,10 @@ class Link(ABC):
|
|
207
219
|
if 'bind_netns' in self.settings:
|
208
220
|
del(self.settings['bind_netns'])
|
209
221
|
|
222
|
+
for attr in self.attr_empty_unset:
|
223
|
+
if attr in self.settings and self.settings[attr] == "":
|
224
|
+
self.settings[attr] = None
|
225
|
+
|
210
226
|
def search_link_registry(self):
|
211
227
|
for args in self.link_registry_search_args:
|
212
228
|
item = self.ifstate.link_registry.get_link(**args)
|
@@ -722,6 +738,12 @@ class Link(ABC):
|
|
722
738
|
if setting in self.settings:
|
723
739
|
skipped_settings[setting] = self.settings.pop(setting)
|
724
740
|
|
741
|
+
# handle settings which are unset using empty strings (i.e. ifstate)
|
742
|
+
for setting in self.attr_empty_unset:
|
743
|
+
if setting in self.settings and self.settings[setting] == None:
|
744
|
+
skipped_settings[setting] = self.settings.pop(setting)
|
745
|
+
self.settings[setting] = ""
|
746
|
+
|
725
747
|
if has_ifname_change:
|
726
748
|
self.prevent_altname_conflict()
|
727
749
|
|
@@ -737,6 +759,10 @@ class Link(ABC):
|
|
737
759
|
# None index references are configuration via the invalid ifindex 0
|
738
760
|
value = 0
|
739
761
|
|
762
|
+
# these attributes are not returned if unset (i.e. ifstate)
|
763
|
+
if setting in self.attr_empty_unset and value == None:
|
764
|
+
value = ""
|
765
|
+
|
740
766
|
if value != self.settings[setting]:
|
741
767
|
if self.cap_create:
|
742
768
|
logger.debug(' %s: setting could not be changed', setting, extra={'iface': self.settings['ifname']})
|
@@ -157,7 +157,21 @@ class Tables(collections.abc.Mapping):
|
|
157
157
|
rt['oif'] = route['dev']
|
158
158
|
|
159
159
|
if 'via' in route:
|
160
|
-
|
160
|
+
via = ip_address(route['via'])
|
161
|
+
|
162
|
+
if via.version == dst.version:
|
163
|
+
rt['gateway'] = str(via)
|
164
|
+
else:
|
165
|
+
if via.version == 4:
|
166
|
+
rt['via'] = {
|
167
|
+
'family': int(AF_INET),
|
168
|
+
'addr': str(via),
|
169
|
+
}
|
170
|
+
else:
|
171
|
+
rt['via'] = {
|
172
|
+
'family': int(AF_INET6),
|
173
|
+
'addr': str(via),
|
174
|
+
}
|
161
175
|
|
162
176
|
if 'src' in route:
|
163
177
|
rt['prefsrc'] = route['src']
|
@@ -219,6 +233,10 @@ class Tables(collections.abc.Mapping):
|
|
219
233
|
via = route.get_attr('RTA_GATEWAY')
|
220
234
|
if via:
|
221
235
|
rt['via'] = via
|
236
|
+
else:
|
237
|
+
via = route.get_attr('RTA_VIA')
|
238
|
+
if via and 'addr' in via:
|
239
|
+
rt['via'] = via['addr']
|
222
240
|
|
223
241
|
realm = route.get_attr('RTA_FLOW')
|
224
242
|
if realm:
|
@@ -280,6 +298,10 @@ class Tables(collections.abc.Mapping):
|
|
280
298
|
if not gateway is None:
|
281
299
|
rt['gateway'] = str(ip_address(gateway))
|
282
300
|
|
301
|
+
via = route.get_attr('RTA_VIA')
|
302
|
+
if not via is None:
|
303
|
+
rt['via'] = via
|
304
|
+
|
283
305
|
metric = route.get_attr('RTA_PRIORITY')
|
284
306
|
if not metric is None:
|
285
307
|
rt['metric'] = metric
|
@@ -307,7 +329,7 @@ class Tables(collections.abc.Mapping):
|
|
307
329
|
|
308
330
|
kroutes = self.kernel_routes(table)
|
309
331
|
|
310
|
-
for route in sorted(croutes, key=lambda x: [x.get('via', ''), x['dst']]):
|
332
|
+
for route in sorted(croutes, key=lambda x: [str(x.get('gateway', x.get('via', ''))), x['dst']]):
|
311
333
|
if 'oif' in route and type(route['oif']) == str:
|
312
334
|
oif = next(
|
313
335
|
iter(self.netns.ipr.link_lookup(ifname=route['oif'])), None)
|
@@ -2318,8 +2318,10 @@
|
|
2318
2318
|
{
|
2319
2319
|
"description": "Virtual Routing and Forwarding device",
|
2320
2320
|
"required": [
|
2321
|
-
"kind"
|
2321
|
+
"kind",
|
2322
|
+
"vrf_table"
|
2322
2323
|
],
|
2324
|
+
"additionalProperties": false,
|
2323
2325
|
"properties": {
|
2324
2326
|
"kind": {
|
2325
2327
|
"const": "vrf",
|
@@ -2343,6 +2345,15 @@
|
|
2343
2345
|
"txqlen": {
|
2344
2346
|
"$ref": "#/$defs/iface-link_txqlen"
|
2345
2347
|
},
|
2348
|
+
"vrf_table": {
|
2349
|
+
"description": "routing table associated with the VRF device",
|
2350
|
+
"type": [
|
2351
|
+
"integer",
|
2352
|
+
"string"
|
2353
|
+
],
|
2354
|
+
"minimum": 1,
|
2355
|
+
"maximum": 4294967295
|
2356
|
+
},
|
2346
2357
|
"ifalias": {
|
2347
2358
|
"$ref": "#/$defs/iface-link_ifalias"
|
2348
2359
|
}
|
@@ -3081,15 +3092,13 @@
|
|
3081
3092
|
},
|
3082
3093
|
"vxlan_local": {
|
3083
3094
|
"type": "string",
|
3084
|
-
"description": "tunnel source
|
3085
|
-
"
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
}
|
3092
|
-
]
|
3095
|
+
"description": "tunnel source IPv4 address",
|
3096
|
+
"format": "ipv4"
|
3097
|
+
},
|
3098
|
+
"vxlan_local6": {
|
3099
|
+
"type": "string",
|
3100
|
+
"description": "tunnel source IPv6 address",
|
3101
|
+
"format": "ipv6"
|
3093
3102
|
},
|
3094
3103
|
"vxlan_group": {
|
3095
3104
|
"type": "string",
|
@@ -3129,10 +3138,32 @@
|
|
3129
3138
|
"vxlan_group"
|
3130
3139
|
]
|
3131
3140
|
},
|
3141
|
+
{
|
3142
|
+
"required": [
|
3143
|
+
"vxlan_local"
|
3144
|
+
]
|
3145
|
+
},
|
3146
|
+
{
|
3147
|
+
"required": [
|
3148
|
+
"vxlan_local",
|
3149
|
+
"vxlan_group"
|
3150
|
+
]
|
3151
|
+
},
|
3132
3152
|
{
|
3133
3153
|
"required": [
|
3134
3154
|
"vxlan_group6"
|
3135
3155
|
]
|
3156
|
+
},
|
3157
|
+
{
|
3158
|
+
"required": [
|
3159
|
+
"vxlan_local6"
|
3160
|
+
]
|
3161
|
+
},
|
3162
|
+
{
|
3163
|
+
"required": [
|
3164
|
+
"vxlan_group6",
|
3165
|
+
"vxlan_local6"
|
3166
|
+
]
|
3136
3167
|
}
|
3137
3168
|
]
|
3138
3169
|
},
|
@@ -3140,7 +3171,9 @@
|
|
3140
3171
|
"not": {
|
3141
3172
|
"required": [
|
3142
3173
|
"vxlan_group",
|
3143
|
-
"vxlan_group6"
|
3174
|
+
"vxlan_group6",
|
3175
|
+
"vxlan_local",
|
3176
|
+
"vxlan_local6"
|
3144
3177
|
]
|
3145
3178
|
}
|
3146
3179
|
}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|