Commit dde4d592 authored by David Johnson's avatar David Johnson

Add nftables expr helpers: counter, mark, l4proto, dscp.

These construct nftables matching and payload mangling expressions, and
dscp supports both ip and ip6.
parent dad3733c
......@@ -35,6 +35,106 @@ def verdict(code):
return [genex('immediate', kwarg), ]
def counter(bytes=0,packets=0):
kwarg = OrderedDict()
kwarg['bytes'] = bytes
kwarg['packets'] = packets
return [genex('counter', kwarg), ]
def mark(match=None,cmp_op=0,new=None):
ret = []
if match is not None:
kwarg = OrderedDict()
kwarg['key'] = 3 # NFT_META_MARK
kwarg['dreg'] = 1
ret.append(genex('meta', kwarg))
kwarg = OrderedDict()
kwarg['sreg'] = 1
kwarg['op'] = cmp_op
kwarg['data'] = {'attrs': [('NFTA_DATA_VALUE',struct.pack('I',match))]}
ret.append(genex('cmp', kwarg))
if new is not None:
kwarg = OrderedDict()
kwarg['dreg'] = 1
kwarg['data'] = {'attrs': [('NFTA_DATA_VALUE', struct.pack('I',new))]}
ret.append(genex('immediate', kwarg))
kwarg = OrderedDict()
kwarg['key'] = 3 # NFT_META_MARK
kwarg['sreg'] = 1
ret.append(genex('meta', kwarg))
return ret
def l4proto(proto,cmp_op=0):
ret = []
kwarg = OrderedDict()
kwarg['key'] = 16 # NFT_META_L4PROTO
kwarg['dreg'] = 1
ret.append(genex('meta', kwarg))
kwarg = OrderedDict()
kwarg['sreg'] = 1
kwarg['op'] = cmp_op
kwarg['data'] = {'attrs': [('NFTA_DATA_VALUE',proto)]}
ret.append(genex('cmp', kwarg))
return ret
def dscp(match=None,cmp_op=0,new=None,family=socket.AF_INET):
ret = []
if family == socket.AF_INET6:
offset = 0
length = 2
shift = 6
packchr = 'H'
else:
offset = 1
length = 1
shift = 0
packchar = 'B'
kwarg = OrderedDict()
kwarg['dreg'] = 1
kwarg['base'] = 1 # NFT_PAYLOAD_NETWORK_HEADER
kwarg['offset'] = offset
kwarg['len'] = length
ret.append(genex('payload', kwarg))
if match is not None:
kwarg = OrderedDict()
kwarg['sreg'] = 1
kwarg['dreg'] = 2 if new is not None else 1
kwarg['len'] = length
kwarg['mask'] = {'attrs': [('NFTA_DATA_VALUE', struct.pack('!%s' % (packchr,),(2**6-1) << shift))]}
kwarg['xor'] = {'attrs': [('NFTA_DATA_VALUE', struct.pack('!%s' % (packchr,),0))]}
ret.append(genex('bitwise', kwarg))
kwarg = OrderedDict()
kwarg['sreg'] = 2 if new is not None else 1
kwarg['op'] = cmp_op
kwarg['data'] = {'attrs': [('NFTA_DATA_VALUE', struct.pack('!%s' % (packchr,),match << shift))]}
ret.append(genex('cmp', kwarg))
if new is not None:
kwarg = OrderedDict()
kwarg['sreg'] = 1
kwarg['dreg'] = 1
kwarg['len'] = length
if family == socket.AF_INET6:
kwarg['mask'] = {'attrs': [('NFTA_DATA_VALUE', struct.pack('!H',61503))]}
kwarg['xor'] = {'attrs': [('NFTA_DATA_VALUE', struct.pack('!H',new << 6))]}
else:
kwarg['mask'] = {'attrs': [('NFTA_DATA_VALUE', struct.pack('B',2**6-1))]}
kwarg['xor'] = {'attrs': [('NFTA_DATA_VALUE', struct.pack('!%s' % (packchr,),0))]}
ret.append(genex('bitwise', kwarg))
kwarg = OrderedDict()
kwarg['sreg'] = 1
kwarg['base'] = 1 # NFT_PAYLOAD_NETWORK_HEADER
kwarg['offset'] = offset
kwarg['len'] = length
kwarg['csum_type'] = 0 # NFT_PAYLOAD_CSUM_NONE
kwarg['csum_offset'] = 0
kwarg['csum_flags'] = 0
ret.append(genex('payload', kwarg))
return ret
def ipv4addr(src=None, dst=None):
if not src and not dst:
raise ValueError('must be at least one of src, dst')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment