Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/tcpip/nftables/nft_bitwise.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ func (op bitwise) evaluate(regs *registerSet, pkt *stack.PacketBuffer, rule *Rul
}

func (op bitwise) GetExprName() string {
return "bitwise"
return OpTypeBitwise.String()
}

// TODO: b/452648112 - Implement dump for bitwise operation.
Expand Down
2 changes: 1 addition & 1 deletion pkg/tcpip/nftables/nft_byteorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func (op byteorder) evaluate(regs *registerSet, pkt *stack.PacketBuffer, rule *R
}

func (op byteorder) GetExprName() string {
return "byteorder"
return OpTypeByteorder.String()
}

// TODO: b/452648112 - Implement dump for last operation.
Expand Down
2 changes: 1 addition & 1 deletion pkg/tcpip/nftables/nft_comparison.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func (op comparison) evaluate(regs *registerSet, pkt *stack.PacketBuffer, rule *
}
}
func (op comparison) GetExprName() string {
return "cmp"
return OpTypeComparison.String()
}

func (op comparison) Dump() ([]byte, *syserr.AnnotatedError) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/tcpip/nftables/nft_counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (op *counter) evaluate(regs *registerSet, pkt *stack.PacketBuffer, rule *Ru
}

func (op *counter) GetExprName() string {
return "counter"
return OpTypeCounter.String()
}

func (op *counter) Dump() ([]byte, *syserr.AnnotatedError) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/tcpip/nftables/nft_immediate.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (op immediate) evaluate(regs *registerSet, pkt *stack.PacketBuffer, rule *R
}

func (op immediate) GetExprName() string {
return "immediate"
return OpTypeImmediate.String()
}

func (op immediate) Dump() ([]byte, *syserr.AnnotatedError) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/tcpip/nftables/nft_last.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (op *last) evaluate(regs *registerSet, pkt *stack.PacketBuffer, rule *Rule)
}

func (op *last) GetExprName() string {
return "last"
return OpTypeLast.String()
}

// TODO: b/452648112 - Implement dump for last operation.
Expand Down
2 changes: 1 addition & 1 deletion pkg/tcpip/nftables/nft_metaload.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func (op metaLoad) evaluate(regs *registerSet, pkt *stack.PacketBuffer, rule *Ru
}

func (op metaLoad) GetExprName() string {
return "meta"
return OpTypeMeta.String()
}

func (op metaLoad) Dump() ([]byte, *syserr.AnnotatedError) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/tcpip/nftables/nft_metaset.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (op metaSet) evaluate(regs *registerSet, pkt *stack.PacketBuffer, rule *Rul
}

func (op metaSet) GetExprName() string {
return "meta"
return OpTypeMeta.String()
}

func (op metaSet) Dump() ([]byte, *syserr.AnnotatedError) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/tcpip/nftables/nft_payload_load.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func initPayloadLoad(tab *Table, attrs map[uint16]nlmsg.BytesView) (*payloadLoad
}

func (op payloadLoad) GetExprName() string {
return "payload"
return OpTypePayload.String()
}

func (op payloadLoad) Dump() ([]byte, *syserr.AnnotatedError) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/tcpip/nftables/nft_payload_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func (op payloadSet) evaluate(regs *registerSet, pkt *stack.PacketBuffer, rule *
}

func (op payloadSet) GetExprName() string {
return "payload"
return OpTypePayload.String()
}

func (op payloadSet) Dump() ([]byte, *syserr.AnnotatedError) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/tcpip/nftables/nft_ranged.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (op ranged) evaluate(regs *registerSet, pkt *stack.PacketBuffer, rule *Rule
}

func (op ranged) GetExprName() string {
return "ranged"
return OpTypeRanged.String()
}

// TODO: b/452648112 - Implement dump for ranged operation.
Expand Down
2 changes: 1 addition & 1 deletion pkg/tcpip/nftables/nft_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func (op route) evaluate(regs *registerSet, pkt *stack.PacketBuffer, rule *Rule)
}

func (op route) GetExprName() string {
return "route"
return OpTypeRoute.String()
}

// TODO: b/452648112 - Implement dump for last operation.
Expand Down
13 changes: 7 additions & 6 deletions pkg/tcpip/nftables/nftables.go
Original file line number Diff line number Diff line change
Expand Up @@ -1180,24 +1180,25 @@ func (r *Rule) AddOpFromExprInfo(tab *Table, exprInfo ExprInfo) *syserr.Annotate
// TODO - b/434244017: Support parsing expression types other than NFT_IMMEDIATE
var op operation
var err *syserr.AnnotatedError
switch exprInfo.ExprName {
case "immediate":
exprOpType := ToOpType(exprInfo.ExprName)
switch exprOpType {
case OpTypeImmediate:
if op, err = initImmediate(tab, exprInfo); err != nil {
return err
}
case "payload":
case OpTypePayload:
if op, err = initPayload(tab, exprInfo); err != nil {
return err
}
case "meta":
case OpTypeMeta:
if op, err = initMeta(tab, exprInfo); err != nil {
return err
}
case "cmp":
case OpTypeComparison:
if op, err = initComparison(tab, exprInfo); err != nil {
return err
}
case "counter":
case OpTypeCounter:
if op, err = initCounter(tab, exprInfo); err != nil {
return err
}
Expand Down
9 changes: 1 addition & 8 deletions pkg/tcpip/nftables/nftables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,14 +412,7 @@ func TestAcceptAllForSupportedHooks(t *testing.T) {
cmpPkt := pkt.Clone()
v, err := nf.EvaluateHook(pktFamily, hook, pkt)

supported := false
for _, h := range supportedHooks[family] {
if h == hook {
supported = true
break
}
}

supported := supportedHooks[family][hook]
if supported {
if err != nil || v.Code != VC(linux.NF_ACCEPT) {
t.Fatalf("expecting accept verdict for EvaluateHook with supported hook %v for family %v; got %v verdict, %s packet, and error %v",
Expand Down
135 changes: 113 additions & 22 deletions pkg/tcpip/nftables/nftables_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,13 @@ func validateAddressFamily(family stack.AddressFamily) *syserr.AnnotatedError {
}

// supportedHooks maps each address family to its supported hooks.
var supportedHooks [stack.NumAFs][]stack.NFHook = [stack.NumAFs][]stack.NFHook{
stack.IP: {stack.NFPrerouting, stack.NFInput, stack.NFForward, stack.NFOutput, stack.NFPostrouting, stack.NFIngress},
stack.IP6: {stack.NFPrerouting, stack.NFInput, stack.NFForward, stack.NFOutput, stack.NFPostrouting, stack.NFIngress},
stack.Inet: {stack.NFPrerouting, stack.NFInput, stack.NFForward, stack.NFOutput, stack.NFPostrouting, stack.NFIngress},
stack.Arp: {stack.NFInput, stack.NFOutput},
stack.Bridge: {stack.NFPrerouting, stack.NFInput, stack.NFForward, stack.NFOutput, stack.NFPostrouting, stack.NFIngress},
stack.Netdev: {stack.NFIngress, stack.NFEgress},
var supportedHooks [stack.NumAFs][stack.NFNumHooks]bool = [stack.NumAFs][stack.NFNumHooks]bool{
stack.IP: {true /*NFPrerouting*/, true /*NFInput*/, true /*NFForward*/, true /*NFOutput*/, true /*NFPostrouting*/, true /*NFIngress*/, false /*NFEgress*/},
stack.IP6: {true /*NFPrerouting*/, true /*NFInput*/, true /*NFForward*/, true /*NFOutput*/, true /*NFPostrouting*/, true /*NFIngress*/, false /*NFEgress*/},
stack.Inet: {true /*NFPrerouting*/, true /*NFInput*/, true /*NFForward*/, true /*NFOutput*/, true /*NFPostrouting*/, true /*NFIngress*/, false /*NFEgress*/},
stack.Arp: {false /*NFPrerouting*/, true /*NFInput*/, false /*NFForward*/, true /*NFOutput*/, false /*NFPostrouting*/, false /*NFIngress*/, false /*NFEgress*/},
stack.Bridge: {true /*NFPrerouting*/, true /*NFInput*/, true /*NFForward*/, true /*NFOutput*/, true /*NFPostrouting*/, true /*NFIngress*/, false /*NFEgress*/},
stack.Netdev: {false /*NFPrerouting*/, false /*NFInput*/, false /*NFForward*/, false /*NFOutput*/, false /*NFPostrouting*/, true /*NFIngress*/, true /*NFEgress*/},
}

// supportedLinuxHooks maps each address family to its supported hooks for each base chain type.
Expand Down Expand Up @@ -160,7 +160,7 @@ func validateHook(hook stack.NFHook, family stack.AddressFamily) *syserr.Annotat
if hook >= stack.NFNumHooks {
return syserr.NewAnnotatedError(syserr.ErrInvalidArgument, fmt.Sprintf("invalid hook: %d", int(hook)))
}
if slices.Contains(supportedHooks[family], hook) {
if supportedHooks[family][hook] {
return nil
}

Expand Down Expand Up @@ -602,44 +602,57 @@ type standardPriority struct {
hooks []stack.NFHook
}

// supportedHooksAsList converts the supported hooks array to a list of hooks.
func supportedHooksAsList(family stack.AddressFamily) []stack.NFHook {
var ret []stack.NFHook
for idx, ok := range supportedHooks[family] {
if ok {
ret = append(ret, stack.NFHook(idx))
}
}
return ret
}

// standardPriorityMatrix is used to look up information for the predefined
// standard priority names.
// TODO: b/493710955 - Not used, clean up.
var standardPriorityMatrix = map[stack.AddressFamily](map[string]standardPriority){
stack.IP: spmIP,
// Note: IPv6 standard priorities constants currently have the same values as
// IPv4's, but the definitions (in the linux kernel) may change in the future.
stack.IP6: map[string]standardPriority{ // from uapi/linux/netfilter_ipv6.h
"raw": {name: "raw", value: linux.NF_IP6_PRI_RAW, hooks: supportedHooks[stack.IP6]},
"mangle": {name: "mangle", value: linux.NF_IP6_PRI_MANGLE, hooks: supportedHooks[stack.IP6]},
"dstnat": {name: "dstnat", value: linux.NF_IP6_PRI_NAT_DST, hooks: []stack.NFHook{stack.NFPrerouting}},
"filter": {name: "filter", value: linux.NF_IP6_PRI_FILTER, hooks: supportedHooks[stack.IP6]},
"security": {name: "security", value: linux.NF_IP6_PRI_SECURITY, hooks: supportedHooks[stack.IP6]},
"srcnat": {name: "srcnat", value: linux.NF_IP6_PRI_NAT_SRC, hooks: []stack.NFHook{stack.NFPostrouting}},
"raw": {name: "raw", value: linux.NF_IP6_PRI_RAW, hooks: supportedHooksAsList(stack.IP6)},
"mangle": {name: "mangle", value: linux.NF_IP6_PRI_MANGLE, hooks: supportedHooksAsList(stack.IP6)},
"dstnat": {name: "dstnat", value: linux.NF_IP6_PRI_NAT_DST, hooks: supportedHooksAsList(stack.IP6)},
"filter": {name: "filter", value: linux.NF_IP6_PRI_FILTER, hooks: supportedHooksAsList(stack.IP6)},
"security": {name: "security", value: linux.NF_IP6_PRI_SECURITY, hooks: supportedHooksAsList(stack.IP6)},
"srcnat": {name: "srcnat", value: linux.NF_IP6_PRI_NAT_SRC, hooks: supportedHooksAsList(stack.IP6)},
},
stack.Inet: spmIP,
stack.Arp: map[string]standardPriority{ // defined as same as IP filter priority
"filter": {name: "filter", value: spmIP["filter"].value, hooks: supportedHooks[stack.Arp]},
"filter": {name: "filter", value: spmIP["filter"].value, hooks: supportedHooksAsList(stack.Arp)},
},
stack.Bridge: map[string]standardPriority{ // from uapi/linux/netfilter_bridge.h
"dstnat": {name: "dstnat", value: linux.NF_BR_PRI_NAT_DST_BRIDGED, hooks: []stack.NFHook{stack.NFPrerouting}},
"filter": {name: "filter", value: linux.NF_BR_PRI_FILTER_BRIDGED, hooks: supportedHooks[stack.Bridge]},
"filter": {name: "filter", value: linux.NF_BR_PRI_FILTER_BRIDGED, hooks: supportedHooksAsList(stack.Bridge)},
"out": {name: "out", value: linux.NF_BR_PRI_NAT_DST_OTHER, hooks: []stack.NFHook{stack.NFOutput}},
"srcnat": {name: "srcnat", value: linux.NF_BR_PRI_NAT_SRC, hooks: []stack.NFHook{stack.NFPostrouting}},
},
stack.Netdev: map[string]standardPriority{ // defined as same as IP filter priority
"filter": {name: "filter", value: spmIP["filter"].value, hooks: supportedHooks[stack.Netdev]},
"filter": {name: "filter", value: spmIP["filter"].value, hooks: supportedHooksAsList(stack.Netdev)},
},
}

// Used in the standardPriorityMatrix above.
// Note: IPv4 and Inet address families use the same standard priority names.
// TODO: b/493710955 - Not used, clean up.
var spmIP = map[string]standardPriority{ // from uapi/linux/netfilter_ipv4.h
"raw": {name: "raw", value: linux.NF_IP_PRI_RAW, hooks: supportedHooks[stack.IP]},
"mangle": {name: "mangle", value: linux.NF_IP_PRI_MANGLE, hooks: supportedHooks[stack.IP]},
"raw": {name: "raw", value: linux.NF_IP_PRI_RAW, hooks: supportedHooksAsList(stack.IP)},
"mangle": {name: "mangle", value: linux.NF_IP_PRI_MANGLE, hooks: supportedHooksAsList(stack.IP)},
"dstnat": {name: "dstnat", value: linux.NF_IP_PRI_NAT_DST, hooks: []stack.NFHook{stack.NFPrerouting}},
"filter": {name: "filter", value: linux.NF_IP_PRI_FILTER, hooks: supportedHooks[stack.IP]},
"security": {name: "security", value: linux.NF_IP_PRI_SECURITY, hooks: supportedHooks[stack.IP]},
"srcnat": {name: "srcnat", value: linux.NF_IP_PRI_NAT_SRC, hooks: []stack.NFHook{stack.NFPostrouting}},
"filter": {name: "filter", value: linux.NF_IP_PRI_FILTER, hooks: supportedHooksAsList(stack.IP)},
"security": {name: "security", value: linux.NF_IP_PRI_SECURITY, hooks: supportedHooksAsList(stack.IP)},
"srcnat": {name: "srcnat", value: linux.NF_IP_PRI_NAT_SRC, hooks: supportedHooksAsList(stack.IP)},
}

// validateBaseChainInfo ensures the base chain info is valid by checking the
Expand Down Expand Up @@ -719,6 +732,84 @@ var (
_ operation = (*metaSet)(nil)
)

// OpType represents the type of operation.
type OpType int

const (
// OpTypeImmediate is the immediate operation type.
OpTypeImmediate OpType = iota
// OpTypeComparison is the comparison operation type.
OpTypeComparison
// OpTypeRanged is the ranged operation type.
OpTypeRanged
// OpTypePayload is the payload operation type.
OpTypePayload
// OpTypeBitwise is the bitwise operation type.
OpTypeBitwise
// OpTypeCounter is the counter operation type.
OpTypeCounter
// OpTypeLast is the last operation type.
OpTypeLast
// OpTypeRoute is the route operation type.
OpTypeRoute
// OpTypeByteorder is the byteorder operation type.
OpTypeByteorder
// OpTypeMeta is the meta operation type.
OpTypeMeta
// OpTypeUnknown is the unknown operation type.
OpTypeUnknown
)

var opTypeStrings = []string{
OpTypeImmediate: "immediate",
OpTypeComparison: "comparison",
OpTypeRanged: "ranged",
OpTypePayload: "payload",
OpTypeBitwise: "bitwise",
OpTypeCounter: "counter",
OpTypeLast: "last",
OpTypeRoute: "route",
OpTypeByteorder: "byteorder",
OpTypeMeta: "meta",
OpTypeUnknown: "unknown",
}

// String returns a string representation of the operation type.
func (o OpType) String() string {
if o >= 0 && o < OpTypeUnknown {
return opTypeStrings[o]
}
return "unknown"
}

// ToOpType converts a string to an operation type.
func ToOpType(s string) OpType {
switch s {
case "immediate":
return OpTypeImmediate
case "cmp":
return OpTypeComparison
case "ranged":
return OpTypeRanged
case "payload":
return OpTypePayload
case "bitwise":
return OpTypeBitwise
case "counter":
return OpTypeCounter
case "last":
return OpTypeLast
case "route":
return OpTypeRoute
case "byteorder":
return OpTypeByteorder
case "meta":
return OpTypeMeta
default:
return OpTypeUnknown
}
}

//
// Register and Register-Related Implementations.
// Note: Registers are represented by type uint8 for the register number.
Expand Down
Loading
Loading