Skip to content

Simplify policy translation between control plane and data plane #2904

@aanm

Description

@aanm

This is a proposal to simplify the logical model of the policy translation between the control plane and the data plane

1) Generate the policy in the control plane in go using maps.

// endpointPolicy is the joined policy map that represents the sum of
// all policies that selects this endpoint
type EndpointPolicy map[NumericIdentity][L4Rule]L7Rule

this would be stored in the endpoint structure for Ingress and Egress.

For example, let's imagine that we have 5 ingress rules:

(FROM -> TO:DESTINATION PORT)
A -> B               // B allows traffic from A
A -> B:80            // B allows traffic from A to port 80
* -> B:83            // B allows traffic from any to port 83
C -> B:81            // B allows traffic from C to port 81
D -> B:81 "GET /foo" // B allows traffic from D to port 81 for http "GET /foo"

The ingress endpointPolicy map of endpoint B will be:

endpointPolicy := map[NumericIdentity][L4Rule]L7Rule{
  0: {
    "83/TCP": "Redirect to 0",
  },
  A: {
    "0": "Redirect to 0",
    "80/TCP": "Redirect to 0",
  },
  C: {
    "81/TCP": "Redirect to 0",
  },
  D: {
    "81/TCP": "Redirect to 10000",
  },
}

This logic map would be passed to BPF which would be in charge of setting up the policies by maps, #defines, programs, etc.

2) BPF datapath's implementation of the endpointPolicy:

We would need to change the policy's map logic to have support for a key with 2 elements plus a value of 3 elements

The translation of the previous endpointPolicy would be:

+-----------------------+----------------------------+
|         KEY           |            VALUE           |
+-IDENTITY-+-PORT/PROTO-+-REDIRECT-+-BYTES-+-PACKETS-+
|    0     |   83/TCP   |    0     |   0   |    0    |
|    A     |      0     |    0     |   0   |    0    |
|    A     |   80/TCP   |    0     |   0   |    0    |
|    C     |   81/TCP   |    0     |   0   |    0    |
|    D     |   81/TCP   |  10000   |   0   |    0    |
+----------+------------+----------+-------+---------+

For every packet received the lookup would be done in the following order:

0) Lookup for "IDENTITY-PORT/PROTO":
    IF exists
      IF VALUE.REDIRECT != 0
        do redirect to proxy
      ELSE
        continue bpf datapath
    ELSE
      go to 1)
1) Lookup for "IDENTITY-0" (to any port from identity):
    IF exists
      IF VALUE.REDIRECT != 0
        do redirect to proxy  (This is actually invalid. L7 requires a L4 port)
      ELSE
        continue bpf datapath
    ELSE
      go to 2)
2) Lookup for "0-PORT/PROTO" (to PORT/PROTO from any identity):
    IF exists
      IF VALUE.REDIRECT != 0
        do redirect to proxy
      ELSE
        continue bpf datapath
    ELSE
      go to 3)
3) Lookup for "0-0" (to any port from any identity):
    IF exists
      IF VALUE.REDIRECT != 0
        do redirect to proxy  (This is actually invalid. L7 requires a L4 port)
      ELSE
        continue bpf datapath
    ELSE
      go to 4)
4) DROP PACKET

Number of total lookups for each packet from:

+-----------+-------------+-------------+
| Packets   |   Lookups   |    Action   |
+-----------+-------------+-------------+
|  A->B:83  |      3      |    ACCEPT   |
|  A->B:80  |      1      |    ACCEPT   |
|  A->B:85  |      2      |    ACCEPT   |
|  C->B:81  |      1      |    ACCEPT   |
|  D->B:81  |      1      | L7 FORWARD  |
|  E->B:80  |      4      |     DROP    |
+-----------+-------------+-------------+

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/enhancementThis would improve or streamline existing functionality.kind/evaluateThis needs consideration of the scope and impact of the change.staleThe stale bot thinks this issue is old. Add "pinned" label to prevent this from becoming stale.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions