diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-02-10 13:23:03 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-02-17 19:02:12 +0100 |
| commit | 9df1a36a98aaf167993501c32ff7a10a38913f50 (patch) | |
| tree | 3147f56e0462b9ac2b6c2b1bfeda4332f9c097c5 /sys/linux/init_iptables.go | |
| parent | 1f693e021993b9ce686952f9f28475684767c458 (diff) | |
sys/linux: add bridge netfilter support
Diffstat (limited to 'sys/linux/init_iptables.go')
| -rw-r--r-- | sys/linux/init_iptables.go | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/sys/linux/init_iptables.go b/sys/linux/init_iptables.go index c33204496..89604e0b1 100644 --- a/sys/linux/init_iptables.go +++ b/sys/linux/init_iptables.go @@ -106,3 +106,64 @@ func (arch *arch) generateNetfilterTable(g *prog.Gen, typ prog.Type, old prog.Ar }) return } + +func (arch *arch) generateEbtables(g *prog.Gen, typ prog.Type, old prog.Arg) ( + arg prog.Arg, calls []*prog.Call) { + if old == nil { + arg = g.GenerateSpecialArg(typ, &calls) + } else { + // TODO(dvyukov): try to restore original hook order after mutation + // instead of assigning brand new offsets. + arg = old + calls = g.MutateArg(arg) + } + hooksField, entriesField := 4, 7 + if g.Target().PtrSize == 8 { + // Account for paddings. + hooksField, entriesField = 5, 9 + } + tableArg := arg.(*prog.UnionArg).Option.(*prog.GroupArg) + entriesPtr := tableArg.Inner[entriesField].(*prog.PointerArg) + entriesArray := entriesPtr.Res.(*prog.GroupArg) + offsets := make([]uint64, len(entriesArray.Inner)) + var pos, totalEntries uint64 + for i, entriesArg0 := range entriesArray.Inner { + entriesArg := entriesArg0.(*prog.GroupArg) + arrayArg := entriesArg.Inner[len(entriesArg.Inner)-1].(*prog.GroupArg) + entriesArg.Inner[2].(*prog.ConstArg).Val = totalEntries + totalEntries += uint64(len(arrayArg.Inner)) + offsets[i] = pos + pos += entriesArg.Size() + } + tableArg.Inner[2].(*prog.ConstArg).Val = totalEntries + if pos != entriesArray.Size() { + panic("netfilter offsets are broken") + } + // Assign offsets to used hooks. + validHooks := tableArg.Inner[1].(*prog.ConstArg).Val + hooksArg := tableArg.Inner[hooksField].(*prog.GroupArg) + for i, hookArg0 := range hooksArg.Inner { + hookArg := hookArg0.(*prog.ConstArg) + if validHooks&(1<<uint(i)) == 0 { + hookArg.Val = 0 + continue + } + addr := g.Target().PhysicalAddr(entriesPtr) + if len(offsets) != 0 { + addr += offsets[0] + offsets = offsets[1:] + } + hookArg.Val = addr + } + return +} + +func (arch *arch) sanitizeEbtables(c *prog.Call) { + // This is very hacky... just as netfilter interfaces. + // setsockopt's len argument must be equal to size of ebt_replace + entries size. + lenArg := c.Args[4].(*prog.ConstArg) + tableArg := c.Args[3].(*prog.PointerArg).Res.(*prog.UnionArg).Option.(*prog.GroupArg) + entriesField := len(tableArg.Inner) - 1 + entriesArg := tableArg.Inner[entriesField].(*prog.PointerArg).Res + lenArg.Val = tableArg.Size() + entriesArg.Size() +} |
