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.
Files changed (42) hide show
  1. {ifstate-1.13.0 → ifstate-1.13.2}/PKG-INFO +1 -1
  2. {ifstate-1.13.0 → ifstate-1.13.2}/ifstate.egg-info/PKG-INFO +1 -1
  3. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/__init__.py +5 -2
  4. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/fdb/__init__.py +37 -31
  5. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/link/base.py +26 -0
  6. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/routing/__init__.py +24 -2
  7. {ifstate-1.13.0 → ifstate-1.13.2}/schema/ifstate.conf.schema.json +44 -11
  8. {ifstate-1.13.0 → ifstate-1.13.2}/LICENSE +0 -0
  9. {ifstate-1.13.0 → ifstate-1.13.2}/README.md +0 -0
  10. {ifstate-1.13.0 → ifstate-1.13.2}/ifstate/__init__.py +0 -0
  11. {ifstate-1.13.0 → ifstate-1.13.2}/ifstate/ifstate.py +0 -0
  12. {ifstate-1.13.0 → ifstate-1.13.2}/ifstate/shell.py +0 -0
  13. {ifstate-1.13.0 → ifstate-1.13.2}/ifstate/vrrp.py +0 -0
  14. {ifstate-1.13.0 → ifstate-1.13.2}/ifstate.egg-info/SOURCES.txt +0 -0
  15. {ifstate-1.13.0 → ifstate-1.13.2}/ifstate.egg-info/dependency_links.txt +0 -0
  16. {ifstate-1.13.0 → ifstate-1.13.2}/ifstate.egg-info/entry_points.txt +0 -0
  17. {ifstate-1.13.0 → ifstate-1.13.2}/ifstate.egg-info/requires.txt +0 -0
  18. {ifstate-1.13.0 → ifstate-1.13.2}/ifstate.egg-info/top_level.txt +0 -0
  19. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/address/__init__.py +0 -0
  20. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/bpf/__init__.py +0 -0
  21. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/bpf/ctypes.py +0 -0
  22. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/bpf/map.py +0 -0
  23. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/brport/__init__.py +0 -0
  24. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/exception.py +0 -0
  25. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/link/__init__.py +0 -0
  26. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/link/dsa.py +0 -0
  27. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/link/physical.py +0 -0
  28. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/link/tun.py +0 -0
  29. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/link/veth.py +0 -0
  30. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/log.py +0 -0
  31. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/neighbour/__init__.py +0 -0
  32. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/netns/__init__.py +0 -0
  33. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/parser/__init__.py +0 -0
  34. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/parser/base.py +0 -0
  35. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/parser/yaml.py +0 -0
  36. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/sysctl/__init__.py +0 -0
  37. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/tc/__init__.py +0 -0
  38. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/util.py +0 -0
  39. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/wireguard/__init__.py +0 -0
  40. {ifstate-1.13.0 → ifstate-1.13.2}/libifstate/xdp/__init__.py +0 -0
  41. {ifstate-1.13.0 → ifstate-1.13.2}/setup.cfg +0 -0
  42. {ifstate-1.13.0 → ifstate-1.13.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ifstate
3
- Version: 1.13.0
3
+ Version: 1.13.2
4
4
  Summary: Manage host interface settings in a declarative manner
5
5
  Home-page: https://ifstate.net/
6
6
  Author: Thomas Liske
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ifstate
3
- Version: 1.13.0
3
+ Version: 1.13.2
4
4
  Summary: Manage host interface settings in a declarative manner
5
5
  Home-page: https://ifstate.net/
6
6
  Author: Thomas Liske
@@ -48,7 +48,7 @@ import json
48
48
  import errno
49
49
  import logging
50
50
 
51
- __version__ = "1.13.0"
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
- # configure fdb entries
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
- rt['gateway'] = str(ip_address(route['via']))
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 ip address",
3085
- "oneOf": [
3086
- {
3087
- "format": "ipv4"
3088
- },
3089
- {
3090
- "format": "ipv6"
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