]>
Commit | Line | Data |
---|---|---|
a489b168 | 1 | /* |
967bb5c5 | 2 | * Copyright (c) 2015-2019 Nicira, Inc. |
a489b168 DDP |
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" | |
2078901a | 20 | #include "conntrack-tp.h" |
a489b168 DDP |
21 | #include "dp-packet.h" |
22 | ||
967bb5c5 | 23 | enum OVS_PACKED_ENUM other_state { |
a489b168 DDP |
24 | OTHERS_FIRST, |
25 | OTHERS_MULTIPLE, | |
26 | OTHERS_BIDIR, | |
27 | }; | |
28 | ||
29 | struct conn_other { | |
30 | struct conn up; | |
967bb5c5 | 31 | enum other_state state; /* 'conn' lock protected. */ |
a489b168 DDP |
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 | { | |
43 | return CONTAINER_OF(conn, struct conn_other, up); | |
44 | } | |
45 | ||
46 | static enum ct_update_res | |
967bb5c5 | 47 | other_conn_update(struct conntrack *ct, struct conn *conn_, |
e6ef6cc6 | 48 | struct dp_packet *pkt OVS_UNUSED, bool reply, long long now) |
a489b168 DDP |
49 | { |
50 | struct conn_other *conn = conn_other_cast(conn_); | |
a867c010 | 51 | enum ct_update_res ret = CT_UPDATE_VALID; |
a489b168 DDP |
52 | |
53 | if (reply && conn->state != OTHERS_BIDIR) { | |
54 | conn->state = OTHERS_BIDIR; | |
55 | } else if (conn->state == OTHERS_FIRST) { | |
56 | conn->state = OTHERS_MULTIPLE; | |
a867c010 | 57 | ret = CT_UPDATE_VALID_NEW; |
a489b168 DDP |
58 | } |
59 | ||
967bb5c5 | 60 | conn_update_expiration(ct, &conn->up, other_timeouts[conn->state], now); |
a489b168 | 61 | |
a867c010 | 62 | return ret; |
a489b168 DDP |
63 | } |
64 | ||
65 | static bool | |
66 | other_valid_new(struct dp_packet *pkt OVS_UNUSED) | |
67 | { | |
68 | return true; | |
69 | } | |
70 | ||
71 | static struct conn * | |
967bb5c5 | 72 | other_new_conn(struct conntrack *ct, struct dp_packet *pkt OVS_UNUSED, |
2078901a | 73 | long long now, uint32_t tp_id) |
a489b168 DDP |
74 | { |
75 | struct conn_other *conn; | |
76 | ||
77 | conn = xzalloc(sizeof *conn); | |
78 | conn->state = OTHERS_FIRST; | |
2078901a | 79 | conn->up.tp_id = tp_id; |
a489b168 | 80 | |
967bb5c5 | 81 | conn_init_expiration(ct, &conn->up, other_timeouts[conn->state], now); |
a489b168 DDP |
82 | |
83 | return &conn->up; | |
84 | } | |
85 | ||
86 | struct ct_l4_proto ct_proto_other = { | |
87 | .new_conn = other_new_conn, | |
88 | .valid_new = other_valid_new, | |
89 | .conn_update = other_conn_update, | |
90 | }; |