Antoni Segura Puimedon has uploaded a new change for review. Change subject: tc: increased parsing capabilities ......................................................................
tc: increased parsing capabilities Change-Id: I95aa9aaaeb0f8e612734b32a578e46fade7fdd9c Signed-off-by: Antoni S. Puimedon <[email protected]> --- M vdsm/network/tc.py 1 file changed, 185 insertions(+), 2 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/11/29211/1 diff --git a/vdsm/network/tc.py b/vdsm/network/tc.py index 35c4a92..1deb6ab 100644 --- a/vdsm/network/tc.py +++ b/vdsm/network/tc.py @@ -192,6 +192,190 @@ MirredAction = namedtuple('MirredAction', 'target') +def _filter_show(dev, parent=None, prio=None): + cmd = [EXT_TC, 'filter', 'show', 'dev', dev] + if parent is not None: + cmd += ['parent', parent] + if prio is not None: + cmd += ['prio', prio] + return _process_request(cmd) + + +def _parse_u32(tokens): + """Returns a dictionary with the parsed information and consumes the parsed + elements from the input list""" + data = {} + while tokens: + token = tokens.pop(0) + if token in ('fh', 'order', 'link'): + data[token] = tokens.pop(0) + elif token in ('*flowid', 'flowid'): + data['flowid'] = tokens.pop(0) + elif token == 'terminal': + data['terminal'] = True + tokens.pop(0) # swallow 'flowid' + tokens.pop(0) # swallow '???' + elif token == 'ht': + tokens.pop(0) + data['ht_divisor'] = tokens.pop(0) + elif token == 'key': + tokens.pop(0) # swallow 'ht' + data['key_ht'] = tokens.pop(0) + tokens.pop(0) # swallow 'bkt' + data['key_bkt'] = tokens.pop(0) + elif token == '???': + continue + elif token == 0: # line break + continue + elif token == 'match': + if tokens[0] != 'IP': + data['match'] = _parse_match_raw(tokens) + else: + data['match'] = _parse_match_ip(tokens) # To implement + elif token == 'action': + try: + data['actions'].append(_parse_action(tokens)) + except KeyError: + data['actions'] = [_parse_action(tokens)] + else: + break # We should not get here unless iproute adds fields. Log? + return data + + +def _parse_skip_line(tokens): + while tokens: + token = tokens.pop(0) + if token == 0: + break + + +_parse_match_ip = _parse_skip_line + + +def _parse_match_raw(tokens): + value, mask = tokens.pop(0).split('/') + value = int(value, 16) + mask = int(mask, 16) + tokens.pop(0) # Swallow 'at' + offset = int(tokens.pop(0)) + return {'value': value, 'mask': mask, 'offset': offset} + + +def _parse_mirred(tokens): + data = {} + action = tokens.pop(0)[1:] # Get the first token without the opening paren + if action == 'unkown': + data['action'] = action + else: + data['action'] = '%s_%s' % (action.lower(), tokens.pop(0).lower()) + tokens.pop(0) # swallow 'to' + tokens.pop(0) # swallow 'device' + data['target'] = tokens.pop(0)[:-1] + data['op'] = tokens.pop(0) + tokens.pop(0) # pop the 0 that marks new line + while tokens: + token = tokens.pop(0) + if token in ('index', 'ref', 'bind'): + data[token] = tokens.pop(0) + elif token == 0: + break + else: + break # We should not get here unless iproute adds fields. Log? + return data + + +FILTER_ACTIONS = {'csum': None, 'gact': None, 'ipt': None, + 'mirred': _parse_mirred, 'nat': None, 'pedit': None, + 'police': None, 'simple': None, 'skbedit': None, 'xt': None} + + +def _parse_action(tokens): + """Returns a dictionary with the parsed information and consumes the parsed + elements from the input list""" + data = {} + while tokens: + token = tokens.pop(0) + if token == 'order': + data[token] = tokens.pop(0) + data['kind'] = tokens.pop(0) + action_opt_parse = FILTER_ACTIONS.get(data['kind']) + if action_opt_parse is not None: + data.update(action_opt_parse(tokens)) + return data + + +FILTER_CLS = {'basic': None, 'cgroup': None, 'flow': None, 'fw': None, + 'route': None, 'rsvp': None, 'tcindex': None, 'u32': _parse_u32} + + +def _filter_parse_general(tokens): + """Returns a dictionary with the parsed information and consumes the parsed + elements from the input list""" + data = {} + tokens.pop(0) # Pop the 'filter' element + while tokens: + token = tokens.pop(0) + if token == 'root': + data['root'] = True + elif token in ('dev', 'parent', 'protocol', 'pref'): + data[token] = tokens.pop(0) + elif token in FILTER_CLS: + data['kind'] = token + break + return data + + +def foo(dev): + out = _filter_show(dev).splitlines() + lines = [] + current = [] + for line in out: + line = line.replace('\t', ' ') + if line.startswith(' '): + current.append(0) + current.extend(line.strip().split()) + else: + if current: + lines.append(current) + current = line.strip().split() + if current: + lines.append(current) + + for tokens in lines: + if tokens[0] == 'filter': + filt = _filter_parse_general(tokens) + cls_parser = FILTER_CLS[filt['kind']] + if cls_parser is not None: + filt[filt['kind']] = cls_parser(tokens) + print filt + + +def _filters(dev, parent=None, out=None): + if out is None: + out = _filter_show(dev, parent=parent) + lines = [] + current = [] + for line in out: + line = line.replace('\t', ' ') + if line.startswith(' '): + current.append(0) + current.extend(line.strip().split()) + else: + if current: + lines.append(current) + current = line.strip().split() + if current: + lines.append(current) + + for tokens in lines: + if tokens[0] == 'filter': + filt = _filter_parse_general(tokens) + cls_parser = FILTER_CLS[filt['kind']] + if cls_parser is not None: + filt[filt['kind']] = cls_parser(tokens) + yield filt + + def filters(dev, parent, out=None): """ Return a (very) limitted information about tc filters on dev @@ -200,8 +384,7 @@ """ if out is None: - out = _process_request([EXT_TC, 'filter', 'show', 'dev', dev, - 'parent', parent]) + out = _filter_show(dev, parent=parent) HEADER = 'filter protocol ip pref ' prio = handle = None -- To view, visit http://gerrit.ovirt.org/29211 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I95aa9aaaeb0f8e612734b32a578e46fade7fdd9c Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Antoni Segura Puimedon <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
