/src/openvswitch/lib/conntrack-other.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2015-2019 Nicira, Inc. |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at: |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #include <config.h> |
18 | | |
19 | | #include "conntrack-private.h" |
20 | | #include "conntrack-tp.h" |
21 | | #include "dp-packet.h" |
22 | | |
23 | | enum OVS_PACKED_ENUM other_state { |
24 | | OTHERS_FIRST, |
25 | | OTHERS_MULTIPLE, |
26 | | OTHERS_BIDIR, |
27 | | }; |
28 | | |
29 | | struct conn_other { |
30 | | struct conn up; |
31 | | enum other_state state; /* 'conn' lock protected. */ |
32 | | }; |
33 | | |
34 | | static const enum ct_timeout other_timeouts[] = { |
35 | | [OTHERS_FIRST] = CT_TM_OTHER_FIRST, |
36 | | [OTHERS_MULTIPLE] = CT_TM_OTHER_MULTIPLE, |
37 | | [OTHERS_BIDIR] = CT_TM_OTHER_BIDIR, |
38 | | }; |
39 | | |
40 | | static struct conn_other * |
41 | | conn_other_cast(const struct conn *conn) |
42 | 0 | { |
43 | 0 | return CONTAINER_OF(conn, struct conn_other, up); |
44 | 0 | } |
45 | | |
46 | | static enum ct_update_res |
47 | | other_conn_update(struct conntrack *ct, struct conn *conn_, |
48 | | struct dp_packet *pkt OVS_UNUSED, bool reply, long long now) |
49 | 0 | { |
50 | 0 | struct conn_other *conn = conn_other_cast(conn_); |
51 | |
|
52 | 0 | if (reply && conn->state != OTHERS_BIDIR) { |
53 | 0 | conn->state = OTHERS_BIDIR; |
54 | 0 | } else if (conn->state == OTHERS_FIRST) { |
55 | 0 | conn->state = OTHERS_MULTIPLE; |
56 | 0 | } |
57 | |
|
58 | 0 | conn_update_expiration(ct, &conn->up, other_timeouts[conn->state], now); |
59 | |
|
60 | 0 | if (conn->state == OTHERS_BIDIR) { |
61 | 0 | return CT_UPDATE_VALID; |
62 | 0 | } |
63 | 0 | return CT_UPDATE_VALID_NEW; |
64 | 0 | } |
65 | | |
66 | | static bool |
67 | | other_valid_new(struct dp_packet *pkt OVS_UNUSED) |
68 | 0 | { |
69 | 0 | return true; |
70 | 0 | } |
71 | | |
72 | | static struct conn * |
73 | | other_new_conn(struct conntrack *ct, struct dp_packet *pkt OVS_UNUSED, |
74 | | long long now, uint32_t tp_id) |
75 | 0 | { |
76 | 0 | struct conn_other *conn; |
77 | |
|
78 | 0 | conn = xzalloc(sizeof *conn); |
79 | 0 | conn->state = OTHERS_FIRST; |
80 | 0 | conn->up.tp_id = tp_id; |
81 | |
|
82 | 0 | conn_init_expiration(ct, &conn->up, other_timeouts[conn->state], now); |
83 | |
|
84 | 0 | return &conn->up; |
85 | 0 | } |
86 | | |
87 | | struct ct_l4_proto ct_proto_other = { |
88 | | .new_conn = other_new_conn, |
89 | | .valid_new = other_valid_new, |
90 | | .conn_update = other_conn_update, |
91 | | }; |