1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-11-28 11:18:11 +00:00

Merge pull request #1121 from GNS3/bfp_filter

BPF filter support
This commit is contained in:
Jeremy Grossmann 2017-07-12 16:22:01 +07:00 committed by GitHub
commit 2e592d3199
5 changed files with 67 additions and 18 deletions

View File

@ -605,13 +605,24 @@ class BaseNode:
yield from self._ubridge_send('bridge reset_packet_filters ' + bridge_name) yield from self._ubridge_send('bridge reset_packet_filters ' + bridge_name)
i = 0 i = 0
for (filter_type, values) in filters.items(): for (filter_type, values) in filters.items():
cmd = "bridge add_packet_filter {bridge_name} {filter_name} {filter_type} {filter_value}".format( if isinstance(values[0], str):
bridge_name=bridge_name, for line in values[0].split('\n'):
filter_name="filter" + str(i), line = line.strip()
filter_type=filter_type, cmd = "bridge add_packet_filter {bridge_name} {filter_name} {filter_type} {filter_value}".format(
filter_value=" ".join([str(v) for v in values])) bridge_name=bridge_name,
yield from self._ubridge_send(cmd) filter_name="filter" + str(i),
i += 1 filter_type=filter_type,
filter_value='"{}" {}'.format(line, " ".join([str(v) for v in values[1:]]))).strip()
yield from self._ubridge_send(cmd)
i += 1
else:
cmd = "bridge add_packet_filter {bridge_name} {filter_name} {filter_type} {filter_value}".format(
bridge_name=bridge_name,
filter_name="filter" + str(i),
filter_type=filter_type,
filter_value=" ".join([str(v) for v in values]))
yield from self._ubridge_send(cmd)
i += 1
@asyncio.coroutine @asyncio.coroutine
def _add_ubridge_ethernet_connection(self, bridge_name, ethernet_interface, block_host_traffic=True): def _add_ubridge_ethernet_connection(self, bridge_name, ethernet_interface, block_host_traffic=True):

View File

@ -36,6 +36,7 @@ FILTERS = [
"name": "Frequency", "name": "Frequency",
"minimum": -1, "minimum": -1,
"maximum": 32767, "maximum": 32767,
"type": "int",
"unit": "th packet" "unit": "th packet"
} }
] ]
@ -49,6 +50,7 @@ FILTERS = [
"name": "Chance", "name": "Chance",
"minimum": 0, "minimum": 0,
"maximum": 100, "maximum": 100,
"type": "int",
"unit": "%" "unit": "%"
} }
] ]
@ -62,13 +64,15 @@ FILTERS = [
"name": "Latency", "name": "Latency",
"minimum": 0, "minimum": 0,
"maximum": 32767, "maximum": 32767,
"unit": "ms" "unit": "ms",
"type": "int"
}, },
{ {
"name": "Jitter (-/+)", "name": "Jitter (-/+)",
"minimum": 0, "minimum": 0,
"maximum": 32767, "maximum": 32767,
"unit": "ms" "unit": "ms",
"type": "int"
} }
] ]
}, },
@ -81,7 +85,19 @@ FILTERS = [
"name": "Chance", "name": "Chance",
"minimum": 0, "minimum": 0,
"maximum": 100, "maximum": 100,
"unit": "%" "unit": "%",
"type": "int"
}
]
},
{
"type": "bpf",
"name": "Berkeley Packet Filter (BPF)",
"description": "This filter will drop any packet matching a BPF expression. Put one expression per line",
"parameters": [
{
"name": "Filters",
"type": "text"
} }
] ]
} }
@ -124,8 +140,14 @@ class Link:
""" """
new_filters = {} new_filters = {}
for (filter, values) in filters.items(): for (filter, values) in filters.items():
values = [int(v) for v in values] new_values = []
if len(values) != 0 and values[0] != 0: for value in values:
if isinstance(value, str):
new_values.append(value.strip("\n "))
else:
new_values.append(int(value))
values = new_values
if len(values) != 0 and values[0] != 0 and values[0] != '':
new_filters[filter] = values new_filters[filter] = values
if new_filters != self.filters: if new_filters != self.filters:

View File

@ -139,9 +139,21 @@ def test_update_ubridge_udp_connection(node, async_run):
def test_ubridge_apply_filters(node, async_run): def test_ubridge_apply_filters(node, async_run):
filters = { filters = {
"latency": [10] "latency": [10],
"bpf": ["icmp[icmptype] == 8\ntcp src port 53"]
} }
node._ubridge_send = AsyncioMagicMock() node._ubridge_send = AsyncioMagicMock()
async_run(node._ubridge_apply_filters("VPCS-10", filters)) async_run(node._ubridge_apply_filters("VPCS-10", filters))
node._ubridge_send.assert_any_call("bridge reset_packet_filters VPCS-10") node._ubridge_send.assert_any_call("bridge reset_packet_filters VPCS-10")
node._ubridge_send.assert_any_call("bridge add_packet_filter VPCS-10 filter0 latency 10") node._ubridge_send.assert_any_call("bridge add_packet_filter VPCS-10 filter0 latency 10")
def test_ubridge_apply_bpf_filters(node, async_run):
filters = {
"bpf": ["icmp[icmptype] == 8\ntcp src port 53"]
}
node._ubridge_send = AsyncioMagicMock()
async_run(node._ubridge_apply_filters("VPCS-10", filters))
node._ubridge_send.assert_any_call("bridge reset_packet_filters VPCS-10")
node._ubridge_send.assert_any_call("bridge add_packet_filter VPCS-10 filter0 bpf \"icmp[icmptype] == 8\"")
node._ubridge_send.assert_any_call("bridge add_packet_filter VPCS-10 filter1 bpf \"tcp src port 53\"")

View File

@ -369,9 +369,10 @@ def test_update_filters(async_run, project, compute):
link.update = AsyncioMagicMock() link.update = AsyncioMagicMock()
assert link._created assert link._created
async_run(link.update_filters({ async_run(link.update_filters({
"packet_loss": ["10"], "packet_loss": [10],
"delay": ["50", "10"], "delay": [50, 10],
"frequency_drop": ["0"] "frequency_drop": [0],
"bpf": [" \n "]
})) }))
assert link.filters == { assert link.filters == {
"packet_loss": [10], "packet_loss": [10],

View File

@ -373,11 +373,14 @@ def test_update(async_run, project):
}, timeout=120) }, timeout=120)
assert link.created assert link.created
async_run(link.update_filters({"drop": [5]})) async_run(link.update_filters({"drop": [5], "bpf": ["icmp[icmptype] == 8"]}))
compute1.put.assert_any_call("/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/nio".format(project.id, node1.id), data={ compute1.put.assert_any_call("/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/nio".format(project.id, node1.id), data={
"lport": 1024, "lport": 1024,
"rhost": "192.168.1.2", "rhost": "192.168.1.2",
"rport": 2048, "rport": 2048,
"type": "nio_udp", "type": "nio_udp",
"filters": {"drop": [5]} "filters": {
"drop": [5],
"bpf": ["icmp[icmptype] == 8"]
}
}, timeout=120) }, timeout=120)