diff --git a/0002-adapt-lstack.patch b/0002-adapt-lstack.patch index 87f36cd..b7c07f8 100644 --- a/0002-adapt-lstack.patch +++ b/0002-adapt-lstack.patch @@ -95,7 +95,7 @@ index 3ecf8d2..1676a71 100644 CFLAGS = -g $(OPTIMIZATION) $(INC) $(SEC_FLAGS) ARFLAGS = crDP diff --git a/src/api/api_lib.c b/src/api/api_lib.c -index ffa14d6..ba9f3c5 100644 +index 60678f8..4cdb965 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -1061,7 +1061,9 @@ netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u1 @@ -109,7 +109,7 @@ index ffa14d6..ba9f3c5 100644 if (bytes_written != NULL) { *bytes_written = API_MSG_VAR_REF(msg).msg.w.offset; diff --git a/src/api/api_msg.c b/src/api/api_msg.c -index 3f08e03..d5a738f 100644 +index 8092be9..d8d6339 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -54,6 +54,11 @@ @@ -124,7 +124,7 @@ index 3f08e03..d5a738f 100644 #include /* netconns are polled once per second (e.g. continue write on memory error) */ -@@ -452,6 +457,14 @@ err_tcp(void *arg, err_t err) +@@ -455,6 +460,14 @@ err_tcp(void *arg, err_t err) old_state = conn->state; conn->state = NETCONN_NONE; @@ -139,7 +139,7 @@ index 3f08e03..d5a738f 100644 SYS_ARCH_UNPROTECT(lev); /* Notify the user layer about a connection error. Used to signal select. */ -@@ -595,6 +608,10 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) +@@ -598,6 +611,10 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); } @@ -150,7 +150,7 @@ index 3f08e03..d5a738f 100644 return ERR_OK; } #endif /* LWIP_TCP */ -@@ -1315,6 +1332,31 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) +@@ -1316,6 +1333,31 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) return ERR_VAL; } @@ -182,7 +182,7 @@ index 3f08e03..d5a738f 100644 LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT); LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect", (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn)); -@@ -1338,6 +1380,7 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) +@@ -1339,6 +1381,7 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) if (was_blocking) { sys_sem_signal(op_completed_sem); } @@ -190,7 +190,7 @@ index 3f08e03..d5a738f 100644 return ERR_OK; } #endif /* LWIP_TCP */ -@@ -1372,6 +1415,7 @@ lwip_netconn_do_connect(void *m) +@@ -1373,6 +1416,7 @@ lwip_netconn_do_connect(void *m) #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: @@ -198,7 +198,7 @@ index 3f08e03..d5a738f 100644 /* Prevent connect while doing any other action. */ if (msg->conn->state == NETCONN_CONNECT) { err = ERR_ALREADY; -@@ -1389,6 +1433,7 @@ lwip_netconn_do_connect(void *m) +@@ -1390,6 +1434,7 @@ lwip_netconn_do_connect(void *m) err = ERR_INPROGRESS; } else { msg->conn->current_msg = msg; @@ -206,7 +206,7 @@ index 3f08e03..d5a738f 100644 /* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()), when the connection is established! */ #if LWIP_TCPIP_CORE_LOCKING -@@ -1402,6 +1447,7 @@ lwip_netconn_do_connect(void *m) +@@ -1403,6 +1448,7 @@ lwip_netconn_do_connect(void *m) } } } @@ -574,10 +574,10 @@ index 0000000..a917cea +#undef CHECK_DLSYM_RET_RETURN +} diff --git a/src/api/sockets.c b/src/api/sockets.c -index 7852635..3262c1b 100644 +index b911194..8df741d 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -62,6 +62,11 @@ +@@ -62,8 +62,21 @@ #include #endif @@ -588,11 +588,6 @@ index 7852635..3262c1b 100644 + #include - #ifdef LWIP_HOOK_FILENAME -@@ -85,13 +90,29 @@ - #define API_SELECT_CB_VAR_ALLOC(name, retblock) API_VAR_ALLOC_EXT(struct lwip_select_cb, MEMP_SELECT_CB, name, retblock) - #define API_SELECT_CB_VAR_FREE(name) API_VAR_FREE(MEMP_SELECT_CB, name) - +#if USE_LIBOS +enum KERNEL_LWIP_PATH { + PATH_KERNEL = 0, @@ -601,6 +596,20 @@ index 7852635..3262c1b 100644 +}; +#endif + + #ifdef LWIP_HOOK_FILENAME + #include LWIP_HOOK_FILENAME + #endif +@@ -92,6 +105,7 @@ + /* Address length safe read and write */ + #if LWIP_SOCKET_HAVE_SA_LEN + ++ + #if LWIP_IPV4 + #define IP4ADDR_SOCKADDR_SET_LEN(sin) \ + (sin)->sin_len = sizeof(struct sockaddr_in) +@@ -130,12 +144,20 @@ + #endif /* LWIP_SOCKET_HAVE_SA_LEN */ + #if LWIP_IPV4 +#if USE_LIBOS +#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \ @@ -610,7 +619,7 @@ index 7852635..3262c1b 100644 + memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0) +#else #define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \ - (sin)->sin_len = sizeof(struct sockaddr_in); \ + IP4ADDR_SOCKADDR_SET_LEN(sin); \ (sin)->sin_family = AF_INET; \ (sin)->sin_port = lwip_htons((port)); \ inet_addr_from_ip4addr(&(sin)->sin_addr, ipaddr); \ @@ -619,7 +628,7 @@ index 7852635..3262c1b 100644 #define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipaddr, port) do { \ inet_addr_to_ip4addr(ip_2_ip4(ipaddr), &((sin)->sin_addr)); \ (port) = lwip_ntohs((sin)->sin_port); }while(0) -@@ -257,7 +278,12 @@ static void lwip_socket_drop_registered_mld6_memberships(int s); +@@ -301,7 +323,12 @@ static void lwip_socket_drop_registered_mld6_memberships(int s); #endif /* LWIP_IPV6_MLD */ /** The global array of available sockets */ @@ -632,7 +641,7 @@ index 7852635..3262c1b 100644 #if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL #if LWIP_TCPIP_CORE_LOCKING -@@ -285,7 +311,7 @@ static struct lwip_select_cb *select_cb_list; +@@ -324,7 +351,7 @@ static struct lwip_select_cb *select_cb_list; /* Forward declaration of some functions */ #if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL @@ -641,7 +650,7 @@ index 7852635..3262c1b 100644 #define DEFAULT_SOCKET_EVENTCB event_callback static void select_check_waiters(int s, int has_recvevent, int has_sendevent, int has_errevent); #else -@@ -411,7 +437,13 @@ static struct lwip_sock * +@@ -450,7 +477,13 @@ static struct lwip_sock * tryget_socket_unconn_nouse(int fd) { int s = fd - LWIP_SOCKET_OFFSET; @@ -656,7 +665,7 @@ index 7852635..3262c1b 100644 LWIP_DEBUGF(SOCKETS_DEBUG, ("tryget_socket_unconn(%d): invalid\n", fd)); return NULL; } -@@ -475,8 +507,13 @@ tryget_socket(int fd) +@@ -514,8 +547,13 @@ tryget_socket(int fd) * @param fd externally used socket index * @return struct lwip_sock for the socket or NULL if not found */ @@ -670,7 +679,7 @@ index 7852635..3262c1b 100644 { struct lwip_sock *sock = tryget_socket(fd); if (!sock) { -@@ -489,6 +526,24 @@ get_socket(int fd) +@@ -528,6 +566,24 @@ get_socket(int fd) return sock; } @@ -695,7 +704,7 @@ index 7852635..3262c1b 100644 /** * Allocate a new socket for a given netconn. * -@@ -504,6 +559,62 @@ alloc_socket(struct netconn *newconn, int accepted) +@@ -543,6 +599,62 @@ alloc_socket(struct netconn *newconn, int accepted) SYS_ARCH_DECL_PROTECT(lev); LWIP_UNUSED_ARG(accepted); @@ -758,7 +767,7 @@ index 7852635..3262c1b 100644 /* allocate a new socket identifier */ for (i = 0; i < NUM_SOCKETS; ++i) { /* Protect socket array */ -@@ -535,6 +646,8 @@ alloc_socket(struct netconn *newconn, int accepted) +@@ -574,6 +686,8 @@ alloc_socket(struct netconn *newconn, int accepted) SYS_ARCH_UNPROTECT(lev); } return -1; @@ -767,7 +776,7 @@ index 7852635..3262c1b 100644 } /** Free a socket (under lock) -@@ -629,10 +742,43 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +@@ -668,10 +782,43 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) SYS_ARCH_DECL_PROTECT(lev); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); @@ -811,8 +820,8 @@ index 7852635..3262c1b 100644 /* wait for a new connection */ err = netconn_accept(sock->conn, &newconn); -@@ -646,6 +792,9 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) - sock_set_errno(sock, err_to_errno(err)); +@@ -685,6 +832,9 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) + set_errno(err_to_errno(err)); } done_socket(sock); +#if USE_LIBOS @@ -821,7 +830,7 @@ index 7852635..3262c1b 100644 return -1; } LWIP_ASSERT("newconn != NULL", newconn != NULL); -@@ -657,7 +806,11 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +@@ -696,7 +846,11 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) done_socket(sock); return -1; } @@ -833,19 +842,19 @@ index 7852635..3262c1b 100644 nsock = &sockets[newsock - LWIP_SOCKET_OFFSET]; /* See event_callback: If data comes in right away after an accept, even -@@ -695,9 +848,11 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +@@ -734,9 +888,11 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) } IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port); +#if !USE_LIBOS - if (*addrlen > tempaddr.sa.sa_len) { - *addrlen = tempaddr.sa.sa_len; + if (*addrlen > IPADDR_SOCKADDR_GET_LEN(&tempaddr)) { + *addrlen = IPADDR_SOCKADDR_GET_LEN(&tempaddr); } +#endif /* USE_LIBOS */ MEMCPY(addr, &tempaddr, *addrlen); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); -@@ -720,11 +875,24 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) +@@ -759,11 +915,24 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) ip_addr_t local_addr; u16_t local_port; err_t err; @@ -871,7 +880,7 @@ index 7852635..3262c1b 100644 if (!SOCK_ADDR_TYPE_MATCH(name, sock)) { /* sockaddr does not match socket type (IPv4/IPv6) */ -@@ -744,6 +912,18 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) +@@ -783,6 +952,18 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) ip_addr_debug_print_val(SOCKETS_DEBUG, local_addr); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port)); @@ -890,7 +899,7 @@ index 7852635..3262c1b 100644 #if LWIP_IPV4 && LWIP_IPV6 /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&local_addr))) { -@@ -776,10 +956,29 @@ lwip_close(int s) +@@ -815,10 +996,29 @@ lwip_close(int s) LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); @@ -920,7 +929,7 @@ index 7852635..3262c1b 100644 if (sock->conn != NULL) { is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP; -@@ -803,6 +1002,13 @@ lwip_close(int s) +@@ -842,6 +1042,13 @@ lwip_close(int s) return -1; } @@ -934,7 +943,7 @@ index 7852635..3262c1b 100644 free_socket(sock, is_tcp); set_errno(0); return 0; -@@ -814,10 +1020,28 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) +@@ -853,10 +1060,28 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) struct lwip_sock *sock; err_t err; @@ -963,7 +972,7 @@ index 7852635..3262c1b 100644 if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) { /* sockaddr does not match socket type (IPv4/IPv6) */ -@@ -862,6 +1086,11 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) +@@ -901,6 +1126,11 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) return -1; } @@ -973,9 +982,9 @@ index 7852635..3262c1b 100644 +#endif /* USE_LIBOS */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); - sock_set_errno(sock, 0); + set_errno(0); done_socket(sock); -@@ -884,10 +1113,29 @@ lwip_listen(int s, int backlog) +@@ -923,10 +1153,29 @@ lwip_listen(int s, int backlog) LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); @@ -1005,7 +1014,7 @@ index 7852635..3262c1b 100644 /* limit the "backlog" parameter to fit in an u8_t */ backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); -@@ -919,6 +1167,9 @@ static ssize_t +@@ -958,6 +1207,9 @@ static ssize_t lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) { u8_t apiflags = NETCONN_NOAUTORCVD; @@ -1015,7 +1024,7 @@ index 7852635..3262c1b 100644 ssize_t recvd = 0; ssize_t recv_left = (len <= SSIZE_MAX) ? (ssize_t)len : SSIZE_MAX; -@@ -938,6 +1189,13 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) +@@ -977,6 +1229,13 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) /* Check if there is data left from the last recv operation. */ if (sock->lastdata.pbuf) { p = sock->lastdata.pbuf; @@ -1029,7 +1038,7 @@ index 7852635..3262c1b 100644 } else { /* No data was left from the previous operation, so we try to get some from the network. */ -@@ -1008,10 +1266,22 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) +@@ -1047,10 +1306,22 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) /* @todo: do we need to support peeking more than one pbuf? */ } while ((recv_left > 0) && !(flags & MSG_PEEK)); lwip_recv_tcp_done: @@ -1052,24 +1061,24 @@ index 7852635..3262c1b 100644 + } + } +#endif - sock_set_errno(sock, 0); + set_errno(0); return recvd; } -@@ -1040,11 +1310,13 @@ lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port, +@@ -1079,11 +1350,13 @@ lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port, #endif /* LWIP_IPV4 && LWIP_IPV6 */ IPADDR_PORT_TO_SOCKADDR(&saddr, fromaddr, port); +#if !USE_LIBOS - if (*fromlen < saddr.sa.sa_len) { + if (*fromlen < IPADDR_SOCKADDR_GET_LEN(&saddr)) { truncated = 1; - } else if (*fromlen > saddr.sa.sa_len) { - *fromlen = saddr.sa.sa_len; + } else if (*fromlen > IPADDR_SOCKADDR_GET_LEN(&saddr)) { + *fromlen = IPADDR_SOCKADDR_GET_LEN(&saddr); } +#endif MEMCPY(from, &saddr, *fromlen); return truncated; } -@@ -1194,6 +1466,43 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 +@@ -1233,6 +1506,43 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 return ERR_OK; } @@ -1113,7 +1122,7 @@ index 7852635..3262c1b 100644 ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) -@@ -1201,6 +1510,15 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, +@@ -1240,6 +1550,15 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, struct lwip_sock *sock; ssize_t ret; @@ -1129,7 +1138,7 @@ index 7852635..3262c1b 100644 LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); sock = get_socket(s); if (!sock) { -@@ -1250,6 +1568,14 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, +@@ -1289,6 +1608,14 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, ssize_t lwip_read(int s, void *mem, size_t len) { @@ -1144,8 +1153,8 @@ index 7852635..3262c1b 100644 return lwip_recvfrom(s, mem, len, 0, NULL, NULL); } -@@ -1283,6 +1609,15 @@ lwip_recvmsg(int s, struct msghdr *message, int flags) - int i; +@@ -1322,6 +1649,15 @@ lwip_recvmsg(int s, struct msghdr *message, int flags) + msg_iovlen_t i; ssize_t buflen; +#if USE_LIBOS @@ -1160,7 +1169,7 @@ index 7852635..3262c1b 100644 LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg(%d, message=%p, flags=0x%x)\n", s, (void *)message, flags)); LWIP_ERROR("lwip_recvmsg: invalid message pointer", message != NULL, return ERR_ARG;); LWIP_ERROR("lwip_recvmsg: unsupported flags", (flags & ~(MSG_PEEK|MSG_DONTWAIT)) == 0, -@@ -1427,6 +1762,15 @@ lwip_sendmsg(int s, const struct msghdr *msg, int flags) +@@ -1466,6 +1802,15 @@ lwip_sendmsg(int s, const struct msghdr *msg, int flags) #endif err_t err = ERR_OK; @@ -1176,22 +1185,7 @@ index 7852635..3262c1b 100644 sock = get_socket(s); if (!sock) { return -1; -@@ -1436,10 +1780,10 @@ lwip_sendmsg(int s, const struct msghdr *msg, int flags) - sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); - LWIP_ERROR("lwip_sendmsg: invalid msghdr iov", msg->msg_iov != NULL, - sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); -- LWIP_ERROR("lwip_sendmsg: maximum iovs exceeded", (msg->msg_iovlen > 0) && (msg->msg_iovlen <= IOV_MAX), -- sock_set_errno(sock, EMSGSIZE); done_socket(sock); return -1;); -- LWIP_ERROR("lwip_sendmsg: unsupported flags", (flags & ~(MSG_DONTWAIT | MSG_MORE)) == 0, -- sock_set_errno(sock, EOPNOTSUPP); done_socket(sock); return -1;); -+ //LWIP_ERROR("lwip_sendmsg: maximum iovs exceeded", (msg->msg_iovlen > 0) && (msg->msg_iovlen <= IOV_MAX), -+ // sock_set_errno(sock, EMSGSIZE); done_socket(sock); return -1;); -+ //LWIP_ERROR("lwip_sendmsg: unsupported flags", (flags & ~(MSG_DONTWAIT | MSG_MORE)) == 0, -+ // sock_set_errno(sock, EOPNOTSUPP); done_socket(sock); return -1;); - - LWIP_UNUSED_ARG(msg->msg_control); - LWIP_UNUSED_ARG(msg->msg_controllen); -@@ -1590,6 +1934,15 @@ lwip_sendto(int s, const void *data, size_t size, int flags, +@@ -1629,6 +1974,15 @@ lwip_sendto(int s, const void *data, size_t size, int flags, u16_t remote_port; struct netbuf buf; @@ -1207,7 +1201,7 @@ index 7852635..3262c1b 100644 sock = get_socket(s); if (!sock) { return -1; -@@ -1688,6 +2041,11 @@ lwip_socket(int domain, int type, int protocol) +@@ -1727,6 +2081,11 @@ lwip_socket(int domain, int type, int protocol) LWIP_UNUSED_ARG(domain); /* @todo: check this */ @@ -1219,7 +1213,7 @@ index 7852635..3262c1b 100644 /* create a netconn */ switch (type) { case SOCK_RAW: -@@ -1744,6 +2102,14 @@ lwip_socket(int domain, int type, int protocol) +@@ -1783,6 +2142,14 @@ lwip_socket(int domain, int type, int protocol) ssize_t lwip_write(int s, const void *data, size_t size) { @@ -1234,7 +1228,7 @@ index 7852635..3262c1b 100644 return lwip_send(s, data, size, 0); } -@@ -2479,7 +2845,7 @@ lwip_poll_should_wake(const struct lwip_select_cb *scb, int fd, int has_recveven +@@ -2518,7 +2885,7 @@ lwip_poll_should_wake(const struct lwip_select_cb *scb, int fd, int has_recveven * NETCONN_EVT_ERROR * This requirement will be asserted in select_check_waiters() */ @@ -1243,7 +1237,7 @@ index 7852635..3262c1b 100644 event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) { int s, check_waiters; -@@ -2528,23 +2894,38 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +@@ -2567,23 +2934,38 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) if (sock->rcvevent > 1) { check_waiters = 0; } @@ -1282,19 +1276,19 @@ index 7852635..3262c1b 100644 break; default: LWIP_ASSERT("unknown event", 0); -@@ -2739,9 +3120,11 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) +@@ -2778,9 +3160,11 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) ip_addr_debug_print_val(SOCKETS_DEBUG, naddr); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port)); +#if !USE_LIBOS - if (*namelen > saddr.sa.sa_len) { - *namelen = saddr.sa.sa_len; + if (*namelen > IPADDR_SOCKADDR_GET_LEN(&saddr)) { + *namelen = IPADDR_SOCKADDR_GET_LEN(&saddr); } +#endif MEMCPY(name, &saddr, *namelen); - sock_set_errno(sock, 0); -@@ -2752,12 +3135,41 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) + set_errno(0); +@@ -2791,12 +3175,41 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) int lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) { @@ -1336,7 +1330,7 @@ index 7852635..3262c1b 100644 return lwip_getaddrname(s, name, namelen, 1); } -@@ -2765,15 +3177,28 @@ int +@@ -2804,15 +3217,28 @@ int lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) { int err; @@ -1365,8 +1359,8 @@ index 7852635..3262c1b 100644 +#endif /* USE_LIBOS */ if ((NULL == optval) || (NULL == optlen)) { - sock_set_errno(sock, EFAULT); -@@ -3211,15 +3636,30 @@ int + set_errno(EFAULT); +@@ -3250,15 +3676,30 @@ int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) { int err = 0; @@ -1397,8 +1391,8 @@ index 7852635..3262c1b 100644 +#endif /* USE_LIBOS */ if (NULL == optval) { - sock_set_errno(sock, EFAULT); -@@ -3333,6 +3773,7 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ + set_errno(EFAULT); +@@ -3372,6 +3813,7 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ case SO_KEEPALIVE: #if SO_REUSE case SO_REUSEADDR: @@ -1406,7 +1400,7 @@ index 7852635..3262c1b 100644 #endif /* SO_REUSE */ if ((optname == SO_BROADCAST) && (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP)) { -@@ -3745,6 +4186,29 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ +@@ -3784,6 +4226,29 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ return err; } @@ -1436,7 +1430,7 @@ index 7852635..3262c1b 100644 int lwip_ioctl(int s, long cmd, void *argp) { -@@ -3757,6 +4221,7 @@ lwip_ioctl(int s, long cmd, void *argp) +@@ -3796,6 +4261,7 @@ lwip_ioctl(int s, long cmd, void *argp) if (!sock) { return -1; } @@ -1444,7 +1438,7 @@ index 7852635..3262c1b 100644 switch (cmd) { #if LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE -@@ -3839,6 +4304,26 @@ lwip_ioctl(int s, long cmd, void *argp) +@@ -3878,6 +4344,26 @@ lwip_ioctl(int s, long cmd, void *argp) * the flag O_NONBLOCK is implemented for F_SETFL. */ int @@ -1471,7 +1465,7 @@ index 7852635..3262c1b 100644 lwip_fcntl(int s, int cmd, int val) { struct lwip_sock *sock = get_socket(s); -@@ -3848,6 +4333,7 @@ lwip_fcntl(int s, int cmd, int val) +@@ -3887,6 +4373,7 @@ lwip_fcntl(int s, int cmd, int val) if (!sock) { return -1; } @@ -1479,7 +1473,7 @@ index 7852635..3262c1b 100644 switch (cmd) { case F_GETFL: -@@ -4163,4 +4649,50 @@ lwip_socket_drop_registered_mld6_memberships(int s) +@@ -4202,4 +4689,50 @@ lwip_socket_drop_registered_mld6_memberships(int s) } #endif /* LWIP_IPV6_MLD */ @@ -1916,7 +1910,7 @@ index 0000000..55561b1 + return (uint8_t*)mz->addr; +} diff --git a/src/api/tcpip.c b/src/api/tcpip.c -index a7e312a..d3d0b55 100644 +index 3aecbd4..05adfe0 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -56,13 +56,13 @@ @@ -1951,7 +1945,7 @@ index a7e312a..d3d0b55 100644 { struct tcpip_msg *msg; LWIP_UNUSED_ARG(arg); -@@ -242,6 +247,9 @@ tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn) +@@ -247,6 +252,9 @@ tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn) #if LWIP_TCPIP_CORE_LOCKING_INPUT err_t ret; LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_inpkt: PACKET %p/%p\n", (void *)p, (void *)inp)); @@ -1961,7 +1955,7 @@ index a7e312a..d3d0b55 100644 LOCK_TCPIP_CORE(); ret = input_fn(p, inp); UNLOCK_TCPIP_CORE(); -@@ -321,6 +329,9 @@ tcpip_callback(tcpip_callback_fn function, void *ctx) +@@ -326,6 +334,9 @@ tcpip_callback(tcpip_callback_fn function, void *ctx) msg->msg.cb.function = function; msg->msg.cb.ctx = ctx; @@ -1971,7 +1965,7 @@ index a7e312a..d3d0b55 100644 sys_mbox_post(&tcpip_mbox, msg); return ERR_OK; } -@@ -357,6 +368,9 @@ tcpip_try_callback(tcpip_callback_fn function, void *ctx) +@@ -362,6 +373,9 @@ tcpip_try_callback(tcpip_callback_fn function, void *ctx) msg->msg.cb.function = function; msg->msg.cb.ctx = ctx; @@ -1981,7 +1975,7 @@ index a7e312a..d3d0b55 100644 if (sys_mbox_trypost(&tcpip_mbox, msg) != ERR_OK) { memp_free(MEMP_TCPIP_MSG_API, msg); return ERR_MEM; -@@ -438,6 +452,9 @@ tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem) +@@ -443,6 +457,9 @@ tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem) { #if LWIP_TCPIP_CORE_LOCKING LWIP_UNUSED_ARG(sem); @@ -1991,7 +1985,7 @@ index a7e312a..d3d0b55 100644 LOCK_TCPIP_CORE(); fn(apimsg); UNLOCK_TCPIP_CORE(); -@@ -475,6 +492,9 @@ tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call) +@@ -480,6 +497,9 @@ tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call) #if LWIP_TCPIP_CORE_LOCKING err_t err; LOCK_TCPIP_CORE(); @@ -2001,7 +1995,7 @@ index a7e312a..d3d0b55 100644 err = fn(call); UNLOCK_TCPIP_CORE(); return err; -@@ -537,6 +557,10 @@ tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx) +@@ -542,6 +562,10 @@ tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx) msg->type = TCPIP_MSG_CALLBACK_STATIC; msg->msg.cb.function = function; msg->msg.cb.ctx = ctx; @@ -2012,7 +2006,7 @@ index a7e312a..d3d0b55 100644 return (struct tcpip_callback_msg *)msg; } -@@ -614,7 +638,9 @@ tcpip_init(tcpip_init_done_fn initfunc, void *arg) +@@ -662,7 +686,9 @@ tcpip_init(tcpip_init_done_fn initfunc, void *arg) } #endif /* LWIP_TCPIP_CORE_LOCKING */ @@ -2038,10 +2032,10 @@ index e5a055b..ebc01a5 100644 $(eval $(call register_dir, core, $(SRC))) diff --git a/src/core/init.c b/src/core/init.c -index 3620e1d..60e1c68 100644 +index 0013a89..5b60ed8 100644 --- a/src/core/init.c +++ b/src/core/init.c -@@ -343,9 +343,7 @@ lwip_init(void) +@@ -349,9 +349,7 @@ lwip_init(void) /* Modules initialization */ stats_init(); @@ -2066,7 +2060,7 @@ index 18514cf..0d39d2d 100644 #if LWIP_IPV4 && LWIP_IPV6 diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c -index 26c26a9..c83afbe 100644 +index e044bff..ef7771f 100644 --- a/src/core/ipv4/ip4.c +++ b/src/core/ipv4/ip4.c @@ -282,7 +282,9 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) @@ -2079,7 +2073,7 @@ index 26c26a9..c83afbe 100644 LWIP_UNUSED_ARG(inp); if (!ip4_canforward(p)) { -@@ -344,7 +346,9 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) +@@ -378,7 +380,9 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) MIB2_STATS_INC(mib2.ipforwdatagrams); IP_STATS_INC(ip.xmit); @@ -2089,7 +2083,7 @@ index 26c26a9..c83afbe 100644 /* don't fragment if interface has mtu set to 0 [loopif] */ if (netif->mtu && (p->tot_len > netif->mtu)) { if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) { -@@ -438,6 +442,8 @@ ip4_input(struct pbuf *p, struct netif *inp) +@@ -472,6 +476,8 @@ ip4_input(struct pbuf *p, struct netif *inp) LWIP_ASSERT_CORE_LOCKED(); @@ -2098,7 +2092,7 @@ index 26c26a9..c83afbe 100644 IP_STATS_INC(ip.recv); MIB2_STATS_INC(mib2.ipinreceives); -@@ -700,13 +706,19 @@ ip4_input(struct pbuf *p, struct netif *inp) +@@ -734,13 +740,19 @@ ip4_input(struct pbuf *p, struct netif *inp) case IP_PROTO_UDPLITE: #endif /* LWIP_UDPLITE */ MIB2_STATS_INC(mib2.ipindelivers); @@ -2118,7 +2112,7 @@ index 26c26a9..c83afbe 100644 break; #endif /* LWIP_TCP */ #if LWIP_ICMP -@@ -755,6 +767,8 @@ ip4_input(struct pbuf *p, struct netif *inp) +@@ -789,6 +801,8 @@ ip4_input(struct pbuf *p, struct netif *inp) ip4_addr_set_any(ip4_current_src_addr()); ip4_addr_set_any(ip4_current_dest_addr()); @@ -2128,7 +2122,7 @@ index 26c26a9..c83afbe 100644 } diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c -index 060d5f3..9d904ec 100644 +index 90e90dd..fad4f40 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -522,6 +522,8 @@ ip6_input(struct pbuf *p, struct netif *inp) @@ -2169,7 +2163,7 @@ index 060d5f3..9d904ec 100644 } diff --git a/src/core/mem.c b/src/core/mem.c -index 315fb3c..84b3fcc 100644 +index 8566edc..3522825 100644 --- a/src/core/mem.c +++ b/src/core/mem.c @@ -381,9 +381,9 @@ LWIP_DECLARE_MEMORY_ALIGNED(ram_heap, MEM_SIZE_ALIGNED + (2U * SIZEOF_STRUCT_MEM @@ -2213,10 +2207,10 @@ index 352ce5a..454ba32 100644 #ifdef LWIP_HOOK_FILENAME #include LWIP_HOOK_FILENAME diff --git a/src/core/netif.c b/src/core/netif.c -index 088b50e..70392cb 100644 +index d3a0677..ded3561 100644 --- a/src/core/netif.c +++ b/src/core/netif.c -@@ -107,12 +107,12 @@ static netif_ext_callback_t *ext_callback; +@@ -110,12 +110,12 @@ static netif_ext_callback_t *ext_callback; #endif #if !LWIP_SINGLE_NETIF @@ -2232,20 +2226,20 @@ index 088b50e..70392cb 100644 #if LWIP_NUM_NETIF_CLIENT_DATA > 0 static u8_t netif_client_id; -@@ -138,7 +138,7 @@ static err_t netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const i +@@ -141,7 +141,7 @@ static err_t netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const i #endif -static struct netif loop_netif; +static PER_THREAD struct netif loop_netif; - /** - * Initialize a lwip network interface structure for a loopback interface + #if LWIP_TESTMODE + struct netif* netif_get_loopif(void) diff --git a/src/core/pbuf.c b/src/core/pbuf.c -index 7638dfd..27afc28 100644 +index 1fb64d4..201ddf3 100644 --- a/src/core/pbuf.c +++ b/src/core/pbuf.c -@@ -737,7 +737,9 @@ pbuf_free(struct pbuf *p) +@@ -739,7 +739,9 @@ pbuf_free(struct pbuf *p) } LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p)); @@ -2255,7 +2249,7 @@ index 7638dfd..27afc28 100644 count = 0; /* de-allocate all consecutive pbufs from the head of the chain that -@@ -794,7 +796,9 @@ pbuf_free(struct pbuf *p) +@@ -796,7 +798,9 @@ pbuf_free(struct pbuf *p) p = NULL; } } @@ -2266,7 +2260,7 @@ index 7638dfd..27afc28 100644 return count; } diff --git a/src/core/stats.c b/src/core/stats.c -index 34e9b27..f7e0604 100644 +index 95445ec..ce6a929 100644 --- a/src/core/stats.c +++ b/src/core/stats.c @@ -47,7 +47,7 @@ @@ -2297,7 +2291,7 @@ index 34e9b27..f7e0604 100644 void stats_display_proto(struct stats_proto *proto, const char *name) diff --git a/src/core/tcp.c b/src/core/tcp.c -index 371db2b..9e75810 100644 +index ea95ffe..24d035c 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -113,6 +113,7 @@ @@ -2443,7 +2437,7 @@ index 371db2b..9e75810 100644 lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN); if (lpcb == NULL) { res = ERR_MEM; -@@ -1015,6 +1056,7 @@ tcp_new_port(void) +@@ -1018,6 +1059,7 @@ tcp_new_port(void) u16_t n = 0; struct tcp_pcb *pcb; @@ -2451,7 +2445,7 @@ index 371db2b..9e75810 100644 again: tcp_port++; if (tcp_port == TCP_LOCAL_PORT_RANGE_END) { -@@ -1032,6 +1074,8 @@ again: +@@ -1035,6 +1077,8 @@ again: } } } @@ -2460,7 +2454,7 @@ index 371db2b..9e75810 100644 return tcp_port; } -@@ -1142,6 +1186,10 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, +@@ -1145,6 +1189,10 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, #endif /* SO_REUSE */ } @@ -2471,7 +2465,7 @@ index 371db2b..9e75810 100644 iss = tcp_next_iss(pcb); pcb->rcv_nxt = 0; pcb->snd_nxt = iss; -@@ -1174,6 +1222,9 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, +@@ -1177,6 +1225,9 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, if (old_local_port != 0) { TCP_RMV(&tcp_bound_pcbs, pcb); } @@ -2481,7 +2475,7 @@ index 371db2b..9e75810 100644 TCP_REG_ACTIVE(pcb); MIB2_STATS_INC(mib2.tcpactiveopens); -@@ -1389,11 +1440,26 @@ tcp_slowtmr_start: +@@ -1392,11 +1443,26 @@ tcp_slowtmr_start: if (prev != NULL) { LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); prev->next = pcb->next; @@ -2508,7 +2502,7 @@ index 371db2b..9e75810 100644 if (pcb_reset) { tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, -@@ -1404,6 +1470,9 @@ tcp_slowtmr_start: +@@ -1407,6 +1473,9 @@ tcp_slowtmr_start: last_state = pcb->state; pcb2 = pcb; pcb = pcb->next; @@ -2518,7 +2512,7 @@ index 371db2b..9e75810 100644 tcp_free(pcb2); tcp_active_pcbs_changed = 0; -@@ -1455,13 +1524,28 @@ tcp_slowtmr_start: +@@ -1458,13 +1527,28 @@ tcp_slowtmr_start: if (prev != NULL) { LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); prev->next = pcb->next; @@ -2547,7 +2541,7 @@ index 371db2b..9e75810 100644 tcp_free(pcb2); } else { prev = pcb; -@@ -2210,6 +2294,14 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) +@@ -2216,6 +2300,14 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); } @@ -2562,7 +2556,7 @@ index 371db2b..9e75810 100644 /** * Calculates a new initial sequence number for new connections. * -@@ -2384,6 +2476,84 @@ tcp_tcp_get_tcp_addrinfo(struct tcp_pcb *pcb, int local, ip_addr_t *addr, u16_t +@@ -2390,6 +2482,84 @@ tcp_tcp_get_tcp_addrinfo(struct tcp_pcb *pcb, int local, ip_addr_t *addr, u16_t return ERR_VAL; } @@ -2648,7 +2642,7 @@ index 371db2b..9e75810 100644 /* Free all ooseq pbufs (and possibly reset SACK state) */ void diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 2202e38..2b4c160 100644 +index c7a1f7b..48ee11d 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -71,21 +71,22 @@ @@ -2728,8 +2722,8 @@ index 2202e38..2b4c160 100644 LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); @@ -263,6 +281,7 @@ tcp_input(struct pbuf *p, struct netif *inp) pcb->local_port == tcphdr->dest && - ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) && - ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { + ip_addr_eq(&pcb->remote_ip, ip_current_src_addr()) && + ip_addr_eq(&pcb->local_ip, ip_current_dest_addr())) { +#if !TCP_PCB_HASH /* Move this PCB to the front of the list so that subsequent lookups will be faster (we exploit locality in TCP segment @@ -2816,14 +2810,14 @@ index 2202e38..2b4c160 100644 tcp_free(pcb); return 1; @@ -649,6 +700,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) - tcp_rst((const struct tcp_pcb *)pcb, ackno, seqno + tcplen, ip_current_dest_addr(), + tcp_rst_netif(ip_data.current_input_netif, ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); } else if (flags & TCP_SYN) { + PERF_UPDATE_POINT(PERF_LAYER_TCP, PERF_POINT_TCP_SYN_RECV); LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); #if TCP_LISTEN_BACKLOG if (pcb->accepts_pending >= pcb->backlog) { -@@ -695,6 +747,9 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) +@@ -698,6 +750,9 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) npcb->netif_idx = pcb->netif_idx; /* Register the new PCB so that we can begin receiving segments for it. */ @@ -2833,7 +2827,7 @@ index 2202e38..2b4c160 100644 TCP_REG_ACTIVE(npcb); /* Parse any options in the SYN. */ -@@ -715,13 +770,18 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) +@@ -718,13 +773,18 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) } #endif @@ -2852,7 +2846,7 @@ index 2202e38..2b4c160 100644 } return; } -@@ -858,6 +918,7 @@ tcp_process(struct tcp_pcb *pcb) +@@ -868,6 +928,7 @@ tcp_process(struct tcp_pcb *pcb) /* received SYN ACK with expected sequence number? */ if ((flags & TCP_ACK) && (flags & TCP_SYN) && (ackno == pcb->lastack + 1)) { @@ -2860,7 +2854,7 @@ index 2202e38..2b4c160 100644 pcb->rcv_nxt = seqno + 1; pcb->rcv_ann_right_edge = pcb->rcv_nxt; pcb->lastack = ackno; -@@ -925,6 +986,7 @@ tcp_process(struct tcp_pcb *pcb) +@@ -940,6 +1001,7 @@ tcp_process(struct tcp_pcb *pcb) /* expected ACK number? */ if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) { pcb->state = ESTABLISHED; @@ -2868,7 +2862,7 @@ index 2202e38..2b4c160 100644 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG if (pcb->listener == NULL) { -@@ -995,6 +1057,9 @@ tcp_process(struct tcp_pcb *pcb) +@@ -1007,6 +1069,9 @@ tcp_process(struct tcp_pcb *pcb) ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); tcp_ack_now(pcb); tcp_pcb_purge(pcb); @@ -2878,7 +2872,7 @@ index 2202e38..2b4c160 100644 TCP_RMV_ACTIVE(pcb); pcb->state = TIME_WAIT; TCP_REG(&tcp_tw_pcbs, pcb); -@@ -1013,6 +1078,9 @@ tcp_process(struct tcp_pcb *pcb) +@@ -1025,6 +1090,9 @@ tcp_process(struct tcp_pcb *pcb) LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); tcp_ack_now(pcb); tcp_pcb_purge(pcb); @@ -2888,7 +2882,7 @@ index 2202e38..2b4c160 100644 TCP_RMV_ACTIVE(pcb); pcb->state = TIME_WAIT; TCP_REG(&tcp_tw_pcbs, pcb); -@@ -1023,6 +1091,9 @@ tcp_process(struct tcp_pcb *pcb) +@@ -1035,6 +1103,9 @@ tcp_process(struct tcp_pcb *pcb) if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) { LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); tcp_pcb_purge(pcb); @@ -2899,10 +2893,10 @@ index 2202e38..2b4c160 100644 pcb->state = TIME_WAIT; TCP_REG(&tcp_tw_pcbs, pcb); diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c -index 8149d39..dac498e 100644 +index 64579ee..74b22b0 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c -@@ -271,7 +271,7 @@ tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length, +@@ -274,7 +274,7 @@ tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length, return p; } #else /* TCP_OVERSIZE */ @@ -2911,7 +2905,7 @@ index 8149d39..dac498e 100644 #endif /* TCP_OVERSIZE */ #if TCP_CHECKSUM_ON_COPY -@@ -640,7 +640,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -643,7 +643,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) ((struct pbuf_rom *)p2)->payload = (const u8_t *)arg + pos; /* Second, allocate a pbuf for the headers. */ @@ -2920,7 +2914,7 @@ index 8149d39..dac498e 100644 /* If allocation fails, we have to deallocate the data pbuf as * well. */ pbuf_free(p2); -@@ -1458,6 +1458,11 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif +@@ -1461,6 +1461,11 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif err_t err; u16_t len; u32_t *opts; @@ -2932,7 +2926,7 @@ index 8149d39..dac498e 100644 #if TCP_CHECKSUM_ON_COPY int seg_chksum_was_swapped = 0; #endif -@@ -1604,6 +1609,9 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif +@@ -1607,6 +1612,9 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif #endif /* CHECKSUM_GEN_TCP */ TCP_STATS_INC(tcp.xmit); @@ -2942,7 +2936,7 @@ index 8149d39..dac498e 100644 NETIF_SET_HINTS(netif, &(pcb->netif_hints)); err = ip_output_if(seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_TCP, netif); -@@ -1618,6 +1626,9 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif +@@ -1621,6 +1629,9 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif } #endif @@ -2952,7 +2946,7 @@ index 8149d39..dac498e 100644 return err; } -@@ -2024,6 +2035,10 @@ tcp_send_empty_ack(struct tcp_pcb *pcb) +@@ -2090,6 +2101,10 @@ tcp_send_empty_ack(struct tcp_pcb *pcb) u8_t optlen, optflags = 0; u8_t num_sacks = 0; @@ -2963,7 +2957,7 @@ index 8149d39..dac498e 100644 LWIP_ASSERT("tcp_send_empty_ack: invalid pcb", pcb != NULL); #if LWIP_TCP_TIMESTAMPS -@@ -2040,6 +2055,9 @@ tcp_send_empty_ack(struct tcp_pcb *pcb) +@@ -2106,6 +2121,9 @@ tcp_send_empty_ack(struct tcp_pcb *pcb) } #endif @@ -2973,7 +2967,7 @@ index 8149d39..dac498e 100644 p = tcp_output_alloc_header(pcb, optlen, 0, lwip_htonl(pcb->snd_nxt)); if (p == NULL) { /* let tcp_fasttmr retry sending this ACK */ -@@ -2064,6 +2082,9 @@ tcp_send_empty_ack(struct tcp_pcb *pcb) +@@ -2130,6 +2148,9 @@ tcp_send_empty_ack(struct tcp_pcb *pcb) tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); } @@ -2984,7 +2978,7 @@ index 8149d39..dac498e 100644 } diff --git a/src/core/timeouts.c b/src/core/timeouts.c -index f37acfe..0542a32 100644 +index 91657eb..477369f 100644 --- a/src/core/timeouts.c +++ b/src/core/timeouts.c @@ -119,9 +119,9 @@ const int lwip_num_cyclic_timers = LWIP_ARRAYSIZE(lwip_cyclic_timers); @@ -3028,7 +3022,7 @@ index f37acfe..0542a32 100644 /* Satisfy the TCP code which calls this function */ void diff --git a/src/core/udp.c b/src/core/udp.c -index 0b609d3..a5f76b9 100644 +index 23c2be2..24fc174 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -207,7 +207,11 @@ udp_input(struct pbuf *p, struct netif *inp) @@ -3855,7 +3849,7 @@ index 0000000..11f94c2 + +#endif /* __LIST_H__ */ diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h -index c2afaf2..6dec8c0 100644 +index be8c22a..55fc413 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -140,8 +140,43 @@ enum netconn_type { @@ -3903,19 +3897,19 @@ index c2afaf2..6dec8c0 100644 * in state NETCONN_NONE! */ enum netconn_state { diff --git a/src/include/lwip/debug.h b/src/include/lwip/debug.h -index 579fd24..f47cbfe 100644 +index 0ec7e76..4986973 100644 --- a/src/include/lwip/debug.h +++ b/src/include/lwip/debug.h -@@ -145,6 +145,7 @@ - ((debug) & LWIP_DBG_ON) && \ - ((debug) & LWIP_DBG_TYPES_ON) && \ - ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ +@@ -146,6 +146,7 @@ + + #define LWIP_DEBUGF(debug, message) do { \ + if (LWIP_DEBUG_ENABLED(debug)) { \ + LWIP_PLATFORM_LOG(debug, STRIP_BRACES(ESC_ARGS message)); \ LWIP_PLATFORM_DIAG(message); \ if ((debug) & LWIP_DBG_HALT) { \ while(1); \ diff --git a/src/include/lwip/def.h b/src/include/lwip/def.h -index dfb266d..fea7187 100644 +index d6bf763..cfc59e2 100644 --- a/src/include/lwip/def.h +++ b/src/include/lwip/def.h @@ -116,6 +116,21 @@ u32_t lwip_htonl(u32_t x); @@ -3941,10 +3935,10 @@ index dfb266d..fea7187 100644 #define ntohs(x) lwip_ntohs(x) #define htonl(x) lwip_htonl(x) diff --git a/src/include/lwip/ip.h b/src/include/lwip/ip.h -index 653c3b2..d560f6b 100644 +index 668d831..db031ba 100644 --- a/src/include/lwip/ip.h +++ b/src/include/lwip/ip.h -@@ -96,9 +96,15 @@ struct ip_pcb { +@@ -107,9 +107,15 @@ struct ip_pcb { /* * Option flags per-socket. These are the same like SO_XXX in sockets.h */ @@ -3960,7 +3954,7 @@ index 653c3b2..d560f6b 100644 /* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ #define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE) -@@ -125,7 +131,7 @@ struct ip_globals +@@ -136,7 +142,7 @@ struct ip_globals /** Destination IP address of current_header */ ip_addr_t current_iphdr_dest; }; @@ -4013,10 +4007,10 @@ index 1630b26..64d8f31 100644 /** diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h -index 9a16ded..057c51f 100644 +index 0cde2c2..1e6dc46 100644 --- a/src/include/lwip/netif.h +++ b/src/include/lwip/netif.h -@@ -406,11 +406,11 @@ struct netif { +@@ -420,11 +420,11 @@ struct netif { #define NETIF_FOREACH(netif) if (((netif) = netif_default) != NULL) #else /* LWIP_SINGLE_NETIF */ /** The list of network interfaces. */ @@ -4031,13 +4025,14 @@ index 9a16ded..057c51f 100644 void netif_init(void); diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h -index d8c82d1..8294cdd 100644 +index c27dd03..b738460 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h -@@ -533,6 +533,22 @@ +@@ -525,6 +525,22 @@ + #define MEMP_NUM_NETCONN 4 #endif - /** ++/** + * MEMP_NUM_SYS_SEM: the number of struct sys_sems. + * (only needed if you use the sequential API, like api_lib.c) + */ @@ -4053,11 +4048,10 @@ index d8c82d1..8294cdd 100644 +#define MEMP_NUM_SYS_MBOX 128 +#endif + -+/** + /** * MEMP_NUM_SELECT_CB: the number of struct lwip_select_cb. * (Only needed if you have LWIP_MPU_COMPATIBLE==1 and use the socket API. - * In that case, you need one per thread calling lwip_select.) -@@ -2232,7 +2248,7 @@ +@@ -2294,7 +2310,7 @@ * MIB2_STATS==1: Stats for SNMP MIB2. */ #if !defined MIB2_STATS || defined __DOXYGEN__ @@ -4066,7 +4060,7 @@ index d8c82d1..8294cdd 100644 #endif #else -@@ -3422,6 +3438,10 @@ +@@ -3484,6 +3500,10 @@ #define TCP_OUTPUT_DEBUG LWIP_DBG_OFF #endif @@ -4077,7 +4071,7 @@ index d8c82d1..8294cdd 100644 /** * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. */ -@@ -3502,6 +3522,46 @@ +@@ -3571,6 +3591,46 @@ #define LWIP_TESTMODE 0 #endif @@ -4143,7 +4137,7 @@ index 669ad4d..395ac0c 100644 * A list of pools of pbuf's used by LWIP. * diff --git a/src/include/lwip/priv/sockets_priv.h b/src/include/lwip/priv/sockets_priv.h -index d8f9904..7268a17 100644 +index c604734..f438206 100644 --- a/src/include/lwip/priv/sockets_priv.h +++ b/src/include/lwip/priv/sockets_priv.h @@ -45,56 +45,17 @@ @@ -4209,10 +4203,10 @@ index d8f9904..7268a17 100644 /** Maximum optlen used by setsockopt/getsockopt */ #define LWIP_SETGETSOCKOPT_MAXOPTLEN LWIP_MAX(16, sizeof(struct ifreq)) diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h -index 72f9126..192edc4 100644 +index a8e87e5..b1380b6 100644 --- a/src/include/lwip/priv/tcp_priv.h +++ b/src/include/lwip/priv/tcp_priv.h -@@ -323,25 +323,42 @@ struct tcp_seg { +@@ -320,25 +320,42 @@ struct tcp_seg { #endif /* LWIP_WND_SCALE */ /* Global variables: */ @@ -4263,7 +4257,7 @@ index 72f9126..192edc4 100644 /* Axioms about the above lists: 1) Every TCP PCB that is not CLOSED is in one of the lists. -@@ -355,6 +372,54 @@ extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS]; +@@ -352,6 +369,54 @@ extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS]; #define TCP_DEBUG_PCB_LISTS 0 #endif #if TCP_DEBUG_PCB_LISTS @@ -4318,7 +4312,7 @@ index 72f9126..192edc4 100644 #define TCP_REG(pcbs, npcb) do {\ struct tcp_pcb *tcp_tmp_pcb; \ LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %"U16_F"\n", (void *)(npcb), (npcb)->local_port)); \ -@@ -387,8 +452,65 @@ extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS]; +@@ -384,8 +449,65 @@ extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS]; LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \ } while(0) @@ -4384,7 +4378,7 @@ index 72f9126..192edc4 100644 #define TCP_REG(pcbs, npcb) \ do { \ (npcb)->next = *pcbs; \ -@@ -415,8 +537,32 @@ extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS]; +@@ -412,8 +534,32 @@ extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS]; (npcb)->next = NULL; \ } while(0) @@ -4444,10 +4438,10 @@ index 9347461..c9ad89c 100644 #define IP_DF 0x4000U /* don't fragment flag */ #define IP_MF 0x2000U /* more fragments flag */ diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h -index d70d36c..345e26c 100644 +index b6f3d52..c8f0fab 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h -@@ -57,6 +57,11 @@ extern "C" { +@@ -64,6 +64,11 @@ extern "C" { /* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED to prevent this code from redefining it. */ @@ -4459,7 +4453,7 @@ index d70d36c..345e26c 100644 #if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED) typedef u8_t sa_family_t; #endif -@@ -69,7 +74,9 @@ typedef u16_t in_port_t; +@@ -76,7 +81,9 @@ typedef u16_t in_port_t; #if LWIP_IPV4 /* members are in network byte order */ struct sockaddr_in { @@ -4469,7 +4463,7 @@ index d70d36c..345e26c 100644 sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; -@@ -90,7 +97,9 @@ struct sockaddr_in6 { +@@ -97,7 +104,9 @@ struct sockaddr_in6 { #endif /* LWIP_IPV6 */ struct sockaddr { @@ -4479,7 +4473,7 @@ index d70d36c..345e26c 100644 sa_family_t sa_family; char sa_data[14]; }; -@@ -189,6 +198,9 @@ struct ifreq { +@@ -198,6 +207,9 @@ struct ifreq { #define SOCK_DGRAM 2 #define SOCK_RAW 3 @@ -4489,20 +4483,20 @@ index d70d36c..345e26c 100644 /* * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c) */ -@@ -221,6 +233,12 @@ struct ifreq { +@@ -229,6 +241,12 @@ struct ifreq { + #define SO_NO_CHECK 0x100a /* don't create UDP checksum */ #define SO_BINDTODEVICE 0x100b /* bind to device */ - /* ++/* + * Level number for (get/set)sockopt() to apply to socket itself. + */ +#define SOL_SOCKET 0xfff /* options for socket level */ +#endif /* USE_LIBOS */ + -+/* + /* * Structure used for manipulating linger option. */ - struct linger { -@@ -228,11 +246,6 @@ struct linger { +@@ -237,11 +255,6 @@ struct linger { int l_linger; /* linger time in seconds */ }; @@ -4514,7 +4508,7 @@ index d70d36c..345e26c 100644 #define AF_UNSPEC 0 #define AF_INET 2 -@@ -276,11 +289,20 @@ struct linger { +@@ -285,11 +298,20 @@ struct linger { /* * Options for level IPPROTO_TCP */ @@ -4535,7 +4529,7 @@ index d70d36c..345e26c 100644 #endif /* LWIP_TCP */ #if LWIP_IPV6 -@@ -483,12 +505,30 @@ typedef struct fd_set +@@ -492,12 +514,30 @@ typedef struct fd_set unsigned char fd_bits [(FD_SETSIZE+7)/8]; } fd_set; @@ -4567,7 +4561,7 @@ index d70d36c..345e26c 100644 /* poll-related defines and types */ /* @todo: find a better way to guard the definition of these defines and types if already defined */ #if !defined(POLLIN) && !defined(POLLOUT) -@@ -511,6 +551,7 @@ struct pollfd +@@ -520,6 +560,7 @@ struct pollfd short revents; }; #endif @@ -4575,7 +4569,7 @@ index d70d36c..345e26c 100644 /** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided * by your system, set this to 0 and include in cc.h */ -@@ -603,8 +644,15 @@ int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptse +@@ -622,8 +663,15 @@ int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptse #if LWIP_SOCKET_POLL int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout); #endif @@ -4591,7 +4585,7 @@ index d70d36c..345e26c 100644 const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size); int lwip_inet_pton(int af, const char *src, void *dst); -@@ -670,10 +718,17 @@ int lwip_inet_pton(int af, const char *src, void *dst); +@@ -689,10 +737,17 @@ int lwip_inet_pton(int af, const char *src, void *dst); #define writev(s,iov,iovcnt) lwip_writev(s,iov,iovcnt) /** @ingroup socket */ #define close(s) lwip_close(s) @@ -4632,7 +4626,7 @@ index b570dba..4470531 100644 #if LWIP_STATS_DISPLAY void stats_display(void); diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h -index daf7599..4f86b46 100644 +index 3991fd6..8248753 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -51,6 +51,11 @@ @@ -4773,7 +4767,7 @@ index daf7599..4f86b46 100644 #define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6) diff --git a/src/include/lwip/tcpip.h b/src/include/lwip/tcpip.h -index 0b8880a..d2c2440 100644 +index 30ce4fe..76e99c1 100644 --- a/src/include/lwip/tcpip.h +++ b/src/include/lwip/tcpip.h @@ -51,7 +51,7 @@ extern "C" { diff --git a/0008-gazelle-fix-lwip_accept-memcpy-sockaddr-large.patch b/0008-gazelle-fix-lwip_accept-memcpy-sockaddr-large.patch index 94eec7f..e48d782 100644 --- a/0008-gazelle-fix-lwip_accept-memcpy-sockaddr-large.patch +++ b/0008-gazelle-fix-lwip_accept-memcpy-sockaddr-large.patch @@ -8,12 +8,12 @@ Subject: [PATCH] [Huawei]gazelle: fix lwip_accept memcpy sockaddr larger than 1 file changed, 2 insertions(+) diff --git a/src/api/sockets.c b/src/api/sockets.c -index eccc7f9..e640945 100644 +index 7ccac78..1c3d4a3 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -860,6 +860,8 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) - if (*addrlen > tempaddr.sa.sa_len) { - *addrlen = tempaddr.sa.sa_len; +@@ -899,6 +899,8 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) + if (*addrlen > IPADDR_SOCKADDR_GET_LEN(&tempaddr)) { + *addrlen = IPADDR_SOCKADDR_GET_LEN(&tempaddr); } +#else + *addrlen = LWIP_MIN(*addrlen, sizeof(tempaddr)); diff --git a/0009-fix-stack-buffer-overflow-when-memcpy-addr.patch b/0009-fix-stack-buffer-overflow-when-memcpy-addr.patch index 38f97ee..6d7d2e9 100644 --- a/0009-fix-stack-buffer-overflow-when-memcpy-addr.patch +++ b/0009-fix-stack-buffer-overflow-when-memcpy-addr.patch @@ -9,21 +9,21 @@ Subject: [PATCH] fix stack-buffer-overflow in lwip_sock_make_addr and 1 file changed, 4 insertions(+) diff --git a/src/api/sockets.c b/src/api/sockets.c -index e640945..7ce9378 100644 +index 1c3d4a3..3a8a74c 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -1319,6 +1319,8 @@ lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port, - } else if (*fromlen > saddr.sa.sa_len) { - *fromlen = saddr.sa.sa_len; +@@ -1323,6 +1323,8 @@ lwip_recv_tcp_done: + add_epoll_event(sock->conn, EPOLLIN); + } } +#else + *fromlen = LWIP_MIN(*fromlen, sizeof(saddr)); #endif - MEMCPY(from, &saddr, *fromlen); - return truncated; -@@ -3133,6 +3135,8 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) - if (*namelen > saddr.sa.sa_len) { - *namelen = saddr.sa.sa_len; + set_errno(0); + return recvd; +@@ -3179,6 +3181,8 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) + if (*namelen > IPADDR_SOCKADDR_GET_LEN(&saddr)) { + *namelen = IPADDR_SOCKADDR_GET_LEN(&saddr); } +#else + *namelen = LWIP_MIN(*namelen, sizeof(saddr)); diff --git a/0016-lstack-support-mysql-mode.patch b/0016-lstack-support-mysql-mode.patch index 0ac7fe1..78a9b1e 100644 --- a/0016-lstack-support-mysql-mode.patch +++ b/0016-lstack-support-mysql-mode.patch @@ -18,10 +18,10 @@ Subject: [PATCH] lstack support mysql mode 11 files changed, 85 insertions(+), 370 deletions(-) diff --git a/src/api/api_msg.c b/src/api/api_msg.c -index d5a738f..3072dd9 100644 +index d8d6339..0f3a5b6 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c -@@ -342,6 +342,12 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +@@ -345,6 +345,12 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) #endif /* LWIP_SO_RCVBUF */ /* Register event with callback */ API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); @@ -34,7 +34,7 @@ index d5a738f..3072dd9 100644 } return ERR_OK; -@@ -457,14 +463,6 @@ err_tcp(void *arg, err_t err) +@@ -460,14 +466,6 @@ err_tcp(void *arg, err_t err) old_state = conn->state; conn->state = NETCONN_NONE; @@ -49,7 +49,7 @@ index d5a738f..3072dd9 100644 SYS_ARCH_UNPROTECT(lev); /* Notify the user layer about a connection error. Used to signal select. */ -@@ -479,6 +477,12 @@ err_tcp(void *arg, err_t err) +@@ -482,6 +480,12 @@ err_tcp(void *arg, err_t err) if (NETCONN_MBOX_VALID(conn, &conn->recvmbox)) { /* use trypost to prevent deadlock */ sys_mbox_trypost(&conn->recvmbox, mbox_msg); @@ -62,7 +62,7 @@ index d5a738f..3072dd9 100644 } /* pass error message to acceptmbox to wake up pending accept */ if (NETCONN_MBOX_VALID(conn, &conn->acceptmbox)) { -@@ -1344,11 +1348,7 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) +@@ -1345,11 +1349,7 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) int s = conn->socket; struct lwip_sock *sock = get_socket_without_errno(s); @@ -94,12 +94,12 @@ index a917cea..eff9f46 100644 err_out: diff --git a/src/api/sockets.c b/src/api/sockets.c -index f44c34f..b032ce9 100644 +index 31dd51c..fe19d7d 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -90,14 +90,6 @@ - #define API_SELECT_CB_VAR_ALLOC(name, retblock) API_VAR_ALLOC_EXT(struct lwip_select_cb, MEMP_SELECT_CB, name, retblock) - #define API_SELECT_CB_VAR_FREE(name) API_VAR_FREE(MEMP_SELECT_CB, name) +@@ -69,14 +69,6 @@ + + #include -#if USE_LIBOS -enum KERNEL_LWIP_PATH { @@ -109,10 +109,10 @@ index f44c34f..b032ce9 100644 -}; -#endif - - #if LWIP_IPV4 - #if USE_LIBOS - #define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \ -@@ -604,8 +596,6 @@ alloc_socket(struct netconn *newconn, int accepted) + #ifdef LWIP_HOOK_FILENAME + #include LWIP_HOOK_FILENAME + #endif +@@ -644,8 +636,6 @@ alloc_socket(struct netconn *newconn, int accepted) * (unless it has been created by accept()). */ sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1); sockets[i].errevent = 0; @@ -121,7 +121,7 @@ index f44c34f..b032ce9 100644 return i + LWIP_SOCKET_OFFSET; } -@@ -714,13 +704,6 @@ free_socket(struct lwip_sock *sock, int is_tcp) +@@ -754,13 +744,6 @@ free_socket(struct lwip_sock *sock, int is_tcp) /* Protect socket array */ SYS_ARCH_PROTECT(lev); @@ -135,7 +135,7 @@ index f44c34f..b032ce9 100644 freed = free_socket_locked(sock, is_tcp, &conn, &lastdata); SYS_ARCH_UNPROTECT(lev); /* don't use 'sock' after this line, as another task might have allocated it */ -@@ -749,34 +732,11 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +@@ -789,34 +772,10 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) SYS_ARCH_DECL_PROTECT(lev); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); @@ -162,7 +162,6 @@ index f44c34f..b032ce9 100644 - } - sys_errno = errno; -#else -+ sock = get_socket(s); if (!sock) { return -1; @@ -171,8 +170,8 @@ index f44c34f..b032ce9 100644 /* wait for a new connection */ err = netconn_accept(sock->conn, &newconn); -@@ -790,9 +750,6 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) - sock_set_errno(sock, err_to_errno(err)); +@@ -830,9 +789,6 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) + set_errno(err_to_errno(err)); } done_socket(sock); -#if USE_LIBOS @@ -181,7 +180,7 @@ index f44c34f..b032ce9 100644 return -1; } LWIP_ASSERT("newconn != NULL", newconn != NULL); -@@ -875,24 +832,11 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) +@@ -915,24 +871,10 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) ip_addr_t local_addr; u16_t local_port; err_t err; @@ -198,7 +197,6 @@ index f44c34f..b032ce9 100644 - return -1; - } -#else -+ sock = get_socket(s); if (!sock) { return -1; @@ -207,7 +205,7 @@ index f44c34f..b032ce9 100644 if (!SOCK_ADDR_TYPE_MATCH(name, sock)) { /* sockaddr does not match socket type (IPv4/IPv6) */ -@@ -912,18 +856,6 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) +@@ -952,18 +894,6 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) ip_addr_debug_print_val(SOCKETS_DEBUG, local_addr); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port)); @@ -226,14 +224,14 @@ index f44c34f..b032ce9 100644 #if LWIP_IPV4 && LWIP_IPV6 /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&local_addr))) { -@@ -953,32 +885,13 @@ lwip_close(int s) +@@ -993,32 +923,12 @@ lwip_close(int s) struct lwip_sock *sock; int is_tcp = 0; err_t err; - int ret = 0; LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); - +- -#if USE_LIBOS - if (posix_api->is_epfd(s)) { - return posix_api->epoll_close_fn(s); @@ -259,7 +257,7 @@ index f44c34f..b032ce9 100644 if (sock->conn != NULL) { is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP; -@@ -1004,7 +917,7 @@ lwip_close(int s) +@@ -1044,7 +954,7 @@ lwip_close(int s) free_socket(sock, is_tcp); set_errno(0); @@ -268,7 +266,7 @@ index f44c34f..b032ce9 100644 } int -@@ -1013,28 +926,10 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) +@@ -1053,28 +963,10 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) struct lwip_sock *sock; err_t err; @@ -297,7 +295,7 @@ index f44c34f..b032ce9 100644 if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) { /* sockaddr does not match socket type (IPv4/IPv6) */ -@@ -1106,29 +1001,10 @@ lwip_listen(int s, int backlog) +@@ -1146,29 +1038,10 @@ lwip_listen(int s, int backlog) LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); @@ -327,7 +325,7 @@ index f44c34f..b032ce9 100644 /* limit the "backlog" parameter to fit in an u8_t */ backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); -@@ -1160,11 +1036,12 @@ static ssize_t +@@ -1200,11 +1073,12 @@ static ssize_t lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) { u8_t apiflags = NETCONN_NOAUTORCVD; @@ -342,7 +340,7 @@ index f44c34f..b032ce9 100644 LWIP_ASSERT("no socket given", sock != NULL); LWIP_ASSERT("this should be checked internally", NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP); -@@ -1173,6 +1050,7 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) +@@ -1213,6 +1087,7 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) apiflags |= NETCONN_DONTBLOCK; } @@ -350,7 +348,7 @@ index f44c34f..b032ce9 100644 do { struct pbuf *p; err_t err; -@@ -1182,13 +1060,6 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) +@@ -1222,13 +1097,6 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) /* Check if there is data left from the last recv operation. */ if (sock->lastdata.pbuf) { p = sock->lastdata.pbuf; @@ -364,11 +362,9 @@ index f44c34f..b032ce9 100644 } else { /* No data was left from the previous operation, so we try to get some from the network. */ -@@ -1258,23 +1129,21 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) - apiflags |= NETCONN_DONTBLOCK | NETCONN_NOFIN; +@@ -1299,24 +1167,18 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) /* @todo: do we need to support peeking more than one pbuf? */ } while ((recv_left > 0) && !(flags & MSG_PEEK)); -+ lwip_recv_tcp_done: -#if USE_LIBOS - if (apiflags & NETCONN_NOAUTORCVD) @@ -392,12 +388,13 @@ index f44c34f..b032ce9 100644 - add_epoll_event(sock->conn, EPOLLIN); - } - } +-#else +- *fromlen = LWIP_MIN(*fromlen, sizeof(saddr)); -#endif -+ - sock_set_errno(sock, 0); + set_errno(0); return recvd; } -@@ -1461,37 +1330,6 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 +@@ -1501,37 +1363,6 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 return ERR_OK; } @@ -435,7 +432,7 @@ index f44c34f..b032ce9 100644 ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) -@@ -1499,15 +1337,6 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, +@@ -1539,15 +1370,6 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, struct lwip_sock *sock; ssize_t ret; @@ -451,7 +448,7 @@ index f44c34f..b032ce9 100644 LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); sock = get_socket(s); if (!sock) { -@@ -1557,14 +1386,6 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, +@@ -1597,14 +1419,6 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, ssize_t lwip_read(int s, void *mem, size_t len) { @@ -466,8 +463,8 @@ index f44c34f..b032ce9 100644 return lwip_recvfrom(s, mem, len, 0, NULL, NULL); } -@@ -1598,15 +1419,6 @@ lwip_recvmsg(int s, struct msghdr *message, int flags) - int i; +@@ -1638,15 +1452,6 @@ lwip_recvmsg(int s, struct msghdr *message, int flags) + msg_iovlen_t i; ssize_t buflen; -#if USE_LIBOS @@ -482,7 +479,7 @@ index f44c34f..b032ce9 100644 LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg(%d, message=%p, flags=0x%x)\n", s, (void *)message, flags)); LWIP_ERROR("lwip_recvmsg: invalid message pointer", message != NULL, return ERR_ARG;); LWIP_ERROR("lwip_recvmsg: unsupported flags", (flags & ~(MSG_PEEK|MSG_DONTWAIT)) == 0, -@@ -1751,15 +1563,6 @@ lwip_sendmsg(int s, const struct msghdr *msg, int flags) +@@ -1791,15 +1596,6 @@ lwip_sendmsg(int s, const struct msghdr *msg, int flags) #endif err_t err = ERR_OK; @@ -498,7 +495,7 @@ index f44c34f..b032ce9 100644 sock = get_socket(s); if (!sock) { return -1; -@@ -1923,15 +1726,6 @@ lwip_sendto(int s, const void *data, size_t size, int flags, +@@ -1963,15 +1759,6 @@ lwip_sendto(int s, const void *data, size_t size, int flags, u16_t remote_port; struct netbuf buf; @@ -514,7 +511,7 @@ index f44c34f..b032ce9 100644 sock = get_socket(s); if (!sock) { return -1; -@@ -2030,11 +1824,6 @@ lwip_socket(int domain, int type, int protocol) +@@ -2070,11 +1857,6 @@ lwip_socket(int domain, int type, int protocol) LWIP_UNUSED_ARG(domain); /* @todo: check this */ @@ -526,7 +523,7 @@ index f44c34f..b032ce9 100644 /* create a netconn */ switch (type) { case SOCK_RAW: -@@ -2091,14 +1880,6 @@ lwip_socket(int domain, int type, int protocol) +@@ -2131,14 +1913,6 @@ lwip_socket(int domain, int type, int protocol) ssize_t lwip_write(int s, const void *data, size_t size) { @@ -541,7 +538,7 @@ index f44c34f..b032ce9 100644 return lwip_send(s, data, size, 0); } -@@ -2884,20 +2665,16 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +@@ -2924,20 +2698,16 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) check_waiters = 0; } #if USE_LIBOS @@ -566,7 +563,7 @@ index f44c34f..b032ce9 100644 break; case NETCONN_EVT_SENDPLUS: if (sock->sendevent) { -@@ -2905,27 +2682,16 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +@@ -2945,27 +2715,16 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) } sock->sendevent = 1; #if USE_LIBOS @@ -594,7 +591,7 @@ index f44c34f..b032ce9 100644 add_epoll_event(conn, EPOLLERR); #endif break; -@@ -3139,41 +2905,12 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) +@@ -3179,41 +2938,12 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) int lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) { @@ -636,7 +633,7 @@ index f44c34f..b032ce9 100644 return lwip_getaddrname(s, name, namelen, 1); } -@@ -3186,23 +2923,11 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +@@ -3226,23 +2956,11 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); #endif /* !LWIP_TCPIP_CORE_LOCKING */ @@ -659,8 +656,8 @@ index f44c34f..b032ce9 100644 -#endif /* USE_LIBOS */ if ((NULL == optval) || (NULL == optlen)) { - sock_set_errno(sock, EFAULT); -@@ -3645,25 +3370,11 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt + set_errno(EFAULT); +@@ -3685,25 +3403,11 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); #endif /* !LWIP_TCPIP_CORE_LOCKING */ @@ -685,8 +682,8 @@ index f44c34f..b032ce9 100644 -#endif /* USE_LIBOS */ if (NULL == optval) { - sock_set_errno(sock, EFAULT); -@@ -4308,26 +4019,6 @@ lwip_ioctl(int s, long cmd, void *argp) + set_errno(EFAULT); +@@ -4348,26 +4052,6 @@ lwip_ioctl(int s, long cmd, void *argp) * the flag O_NONBLOCK is implemented for F_SETFL. */ int @@ -713,7 +710,7 @@ index f44c34f..b032ce9 100644 lwip_fcntl(int s, int cmd, int val) { struct lwip_sock *sock = get_socket(s); -@@ -4337,7 +4028,6 @@ lwip_fcntl(int s, int cmd, int val) +@@ -4377,7 +4061,6 @@ lwip_fcntl(int s, int cmd, int val) if (!sock) { return -1; } @@ -752,10 +749,10 @@ index 55561b1..9a92143 100644 uint32_t sys_now(void) diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c -index dac498e..b99974d 100644 +index 74b22b0..1164c56 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c -@@ -472,6 +472,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -475,6 +475,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) * pos records progress as data is segmented. */ @@ -763,7 +760,7 @@ index dac498e..b99974d 100644 /* Find the tail of the unsent queue. */ if (pcb->unsent != NULL) { u16_t space; -@@ -587,6 +588,13 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -590,6 +591,13 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) pcb->unsent_oversize == 0); #endif /* TCP_OVERSIZE */ } @@ -777,7 +774,7 @@ index dac498e..b99974d 100644 /* * Phase 3: Create new segments. -@@ -604,6 +612,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -607,6 +615,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) u8_t chksum_swapped = 0; #endif /* TCP_CHECKSUM_ON_COPY */ @@ -785,7 +782,7 @@ index dac498e..b99974d 100644 if (apiflags & TCP_WRITE_FLAG_COPY) { /* If copy is set, memory should be allocated and data copied * into pbuf */ -@@ -650,6 +659,10 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -653,6 +662,10 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) /* Concatenate the headers and data pbufs together. */ pbuf_cat(p/*header*/, p2/*data*/); } @@ -813,10 +810,10 @@ index f525bc2..aacc1d2 100644 #endif /* __EVENTPOLL_H__ */ diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h -index f771725..83208bf 100644 +index f666f8f..783acf5 100644 --- a/src/include/lwip/priv/tcp_priv.h +++ b/src/include/lwip/priv/tcp_priv.h -@@ -349,7 +349,7 @@ static inline int vdev_reg_done(enum reg_ring_type reg_type, const struct tcp_pc +@@ -346,7 +346,7 @@ static inline int vdev_reg_done(enum reg_ring_type reg_type, const struct tcp_pc { LWIP_ASSERT("Invalid parameter", pcb != NULL); @@ -826,10 +823,10 @@ index f771725..83208bf 100644 qtuple.src_ip = pcb->local_ip.addr; qtuple.src_port = lwip_htons(pcb->local_port); diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h -index 345e26c..4e7e671 100644 +index c8f0fab..1d63e8f 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h -@@ -647,7 +647,7 @@ int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout); +@@ -666,7 +666,7 @@ int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout); #if USE_LIBOS int lwip_ioctl(int s, long cmd, ...); diff --git a/0023-refactor-event-and-checksum-offload-support.patch b/0023-refactor-event-and-checksum-offload-support.patch index b092d04..1a24f1d 100644 --- a/0023-refactor-event-and-checksum-offload-support.patch +++ b/0023-refactor-event-and-checksum-offload-support.patch @@ -22,7 +22,7 @@ Subject: [PATCH] refactor event and add HW checksum offload create mode 100644 src/include/dpdk_cksum.h diff --git a/src/api/api_msg.c b/src/api/api_msg.c -index 3072dd9..672f022 100644 +index 0f3a5b6..8f20577 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -57,6 +57,7 @@ @@ -33,7 +33,7 @@ index 3072dd9..672f022 100644 #endif #include -@@ -1758,7 +1759,15 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) +@@ -1759,7 +1760,15 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) } else { write_more = 0; } @@ -70,7 +70,7 @@ index bce07f5..3f85bad 100644 { /* the symbol we use here won't be NULL, so we don't need dlerror() diff --git a/src/api/sockets.c b/src/api/sockets.c -index 21de5d9..3d94454 100644 +index f041776..4216986 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -65,6 +65,7 @@ @@ -81,7 +81,7 @@ index 21de5d9..3d94454 100644 #endif #include -@@ -2682,9 +2683,6 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +@@ -2724,9 +2725,6 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) check_waiters = 0; } sock->sendevent = 1; @@ -92,7 +92,7 @@ index 21de5d9..3d94454 100644 case NETCONN_EVT_SENDMINUS: sock->sendevent = 0; diff --git a/src/core/ipv4/icmp.c b/src/core/ipv4/icmp.c -index 59b493a..c58ae25 100644 +index 9a82a67..0404608 100644 --- a/src/core/ipv4/icmp.c +++ b/src/core/ipv4/icmp.c @@ -51,6 +51,10 @@ @@ -124,7 +124,7 @@ index 59b493a..c58ae25 100644 #endif /* CHECKSUM_GEN_IP */ diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c -index c83afbe..1334cdc 100644 +index ef7771f..4623096 100644 --- a/src/core/ipv4/ip4.c +++ b/src/core/ipv4/ip4.c @@ -59,6 +59,10 @@ @@ -138,7 +138,7 @@ index c83afbe..1334cdc 100644 #ifdef LWIP_HOOK_FILENAME #include LWIP_HOOK_FILENAME #endif -@@ -503,8 +507,17 @@ ip4_input(struct pbuf *p, struct netif *inp) +@@ -537,8 +541,17 @@ ip4_input(struct pbuf *p, struct netif *inp) /* verify checksum */ #if CHECKSUM_CHECK_IP IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) { @@ -157,7 +157,7 @@ index c83afbe..1334cdc 100644 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); ip4_debug_print(p); -@@ -972,7 +985,16 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d +@@ -1006,7 +1019,16 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d IPH_CHKSUM_SET(iphdr, 0); #if CHECKSUM_GEN_IP IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { @@ -175,7 +175,7 @@ index c83afbe..1334cdc 100644 #endif /* CHECKSUM_GEN_IP */ #endif /* CHECKSUM_GEN_IP_INLINE */ diff --git a/src/core/ipv4/ip4_frag.c b/src/core/ipv4/ip4_frag.c -index a445530..17a4ccd 100644 +index 5303144..15b61ee 100644 --- a/src/core/ipv4/ip4_frag.c +++ b/src/core/ipv4/ip4_frag.c @@ -51,6 +51,10 @@ @@ -227,7 +227,7 @@ index a445530..17a4ccd 100644 /* No need for separate header pbuf - we allowed room for it in rambuf diff --git a/src/core/pbuf.c b/src/core/pbuf.c -index cd6b558..247681d 100644 +index 9d4e1c8..69a52b6 100644 --- a/src/core/pbuf.c +++ b/src/core/pbuf.c @@ -282,7 +282,7 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) @@ -239,9 +239,9 @@ index cd6b558..247681d 100644 p = lwip_alloc_pbuf(layer, length, type); #else p = (struct pbuf *)mem_malloc(alloc_len); -@@ -1019,6 +1019,13 @@ pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_ +@@ -1016,6 +1016,13 @@ pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_ /* current p_from does not fit into current p_to */ - len_calc = p_to->len - offset_to; + len = p_to->len - offset_to; } + +#if USE_LIBOS && (CHECKSUM_GEN_IP_HW || CHECKSUM_GEN_TCP_HW) @@ -250,11 +250,11 @@ index cd6b558..247681d 100644 + p_to->ol_flags = p_from->ol_flags; +#endif + - len = (u16_t)LWIP_MIN(copy_len, len_calc); + len = LWIP_MIN(copy_len, len); MEMCPY((u8_t *)p_to->payload + offset_to, (u8_t *)p_from->payload + offset_from, len); offset_to += len; diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 0d3a2f1..b1bbe00 100644 +index 1dd0ed6..fa574ff 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -64,6 +64,10 @@ @@ -294,7 +294,7 @@ index 0d3a2f1..b1bbe00 100644 TCP_STATS_INC(tcp.chkerr); goto dropped; diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c -index b99974d..1b0af8d 100644 +index 1164c56..df26e53 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -80,6 +80,13 @@ @@ -311,7 +311,7 @@ index b99974d..1b0af8d 100644 #ifdef LWIP_HOOK_FILENAME #include LWIP_HOOK_FILENAME #endif -@@ -660,8 +667,11 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -663,8 +670,11 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) pbuf_cat(p/*header*/, p2/*data*/); } #else /* USE_LIBOS */ @@ -325,7 +325,7 @@ index b99974d..1b0af8d 100644 #endif /* USE_LIBOS */ queuelen += pbuf_clen(p); -@@ -789,8 +799,13 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -792,8 +802,13 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) /* * Finally update the pcb state. */ @@ -339,7 +339,7 @@ index b99974d..1b0af8d 100644 pcb->snd_queuelen = queuelen; LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", -@@ -1584,6 +1599,11 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif +@@ -1587,6 +1602,11 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif #if CHECKSUM_GEN_TCP IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { @@ -351,7 +351,7 @@ index b99974d..1b0af8d 100644 #if TCP_CHECKSUM_ON_COPY u32_t acc; #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK -@@ -1618,6 +1638,44 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif +@@ -1621,6 +1641,44 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif seg->tcphdr->chksum = ip_chksum_pseudo(seg->p, IP_PROTO_TCP, seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); #endif /* TCP_CHECKSUM_ON_COPY */ @@ -396,10 +396,10 @@ index b99974d..1b0af8d 100644 } #endif /* CHECKSUM_GEN_TCP */ TCP_STATS_INC(tcp.xmit); -@@ -1959,8 +2017,18 @@ tcp_output_control_segment(const struct tcp_pcb *pcb, struct pbuf *p, +@@ -1979,8 +2037,18 @@ tcp_output_control_segment_netif(const struct tcp_pcb *pcb, struct pbuf *p, #if CHECKSUM_GEN_TCP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { - struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload; + IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { + struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload; +#if CHECKSUM_GEN_TCP_HW + if (get_eth_params_tx_ol() & DEV_TX_OFFLOAD_TCP_CKSUM) { + tcph_cksum_set(p, TCP_HLEN); @@ -409,12 +409,12 @@ index b99974d..1b0af8d 100644 + src, dst); + } +#else - tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, - src, dst); + tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, + src, dst); +#endif - } + } #endif - if (pcb != NULL) { + if (pcb != NULL) { diff --git a/src/include/dpdk_cksum.h b/src/include/dpdk_cksum.h new file mode 100644 index 0000000..e57be4d @@ -529,7 +529,7 @@ index 0000000..e57be4d +#endif /* USE_LIBOS */ +#endif /* __DPDK_CKSUM_H__ */ diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h -index 3894574..87cd960 100644 +index b539ad6..fea7be9 100644 --- a/src/include/lwip/pbuf.h +++ b/src/include/lwip/pbuf.h @@ -220,6 +220,15 @@ struct pbuf { @@ -669,7 +669,7 @@ index 36bcaed..eec4e8e 100644 extern void gazelle_init_sock(int32_t fd); #endif /* USE_LIBOS */ diff --git a/src/netif/ethernet.c b/src/netif/ethernet.c -index dd171e2..ab976a8 100644 +index db5c514..0f21ad3 100644 --- a/src/netif/ethernet.c +++ b/src/netif/ethernet.c @@ -56,6 +56,10 @@ @@ -683,7 +683,7 @@ index dd171e2..ab976a8 100644 #ifdef LWIP_HOOK_FILENAME #include LWIP_HOOK_FILENAME #endif -@@ -308,6 +312,10 @@ ethernet_output(struct netif * netif, struct pbuf * p, +@@ -316,6 +320,10 @@ ethernet_output(struct netif * netif, struct pbuf * p, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("ethernet_output: sending packet %p\n", (void *)p)); diff --git a/0024-refactor-pkt-read-send-performance.patch b/0024-refactor-pkt-read-send-performance.patch index 529738a..21b30cd 100644 --- a/0024-refactor-pkt-read-send-performance.patch +++ b/0024-refactor-pkt-read-send-performance.patch @@ -15,10 +15,10 @@ Subject: [PATCH] refactor pkt read/send 8 files changed, 75 insertions(+), 45 deletions(-) diff --git a/src/api/api_msg.c b/src/api/api_msg.c -index 672f022..7839526 100644 +index 8f20577..ab3cfc1 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c -@@ -341,13 +341,12 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +@@ -344,13 +344,12 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) #if LWIP_SO_RCVBUF SYS_ARCH_INC(conn->recv_avail, len); #endif /* LWIP_SO_RCVBUF */ @@ -36,7 +36,7 @@ index 672f022..7839526 100644 #endif } -@@ -479,10 +478,7 @@ err_tcp(void *arg, err_t err) +@@ -482,10 +481,7 @@ err_tcp(void *arg, err_t err) /* use trypost to prevent deadlock */ sys_mbox_trypost(&conn->recvmbox, mbox_msg); #if USE_LIBOS @@ -48,7 +48,7 @@ index 672f022..7839526 100644 #endif } /* pass error message to acceptmbox to wake up pending accept */ -@@ -1356,6 +1352,7 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) +@@ -1357,6 +1353,7 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) } } SET_CONN_TYPE_LIBOS(conn); @@ -79,10 +79,10 @@ index 3f85bad..6afb9c6 100644 err_out: diff --git a/src/api/sockets.c b/src/api/sockets.c -index 3d94454..4d4cea1 100644 +index 4216986..7cdb9d8 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -1039,11 +1039,7 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) +@@ -1076,11 +1076,7 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) { u8_t apiflags = NETCONN_NOAUTORCVD; ssize_t recvd = 0; @@ -94,15 +94,15 @@ index 3d94454..4d4cea1 100644 LWIP_ASSERT("no socket given", sock != NULL); LWIP_ASSERT("this should be checked internally", NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP); -@@ -1134,6 +1130,7 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) - +@@ -1170,6 +1166,7 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) + } while ((recv_left > 0) && !(flags & MSG_PEEK)); lwip_recv_tcp_done: #else /* USE_LIBOS */ + LWIP_UNUSED_ARG(recv_left); recvd = read_lwip_data(sock, flags, apiflags); if (recvd <= 0) { return recvd; -@@ -2667,10 +2664,8 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +@@ -2709,10 +2706,8 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) check_waiters = 0; } #if USE_LIBOS diff --git a/0025-Replace-gettid-with-syscall-SYS_gettid.patch b/0025-Replace-gettid-with-syscall-SYS_gettid.patch index 92abd14..d2113e1 100644 --- a/0025-Replace-gettid-with-syscall-SYS_gettid.patch +++ b/0025-Replace-gettid-with-syscall-SYS_gettid.patch @@ -12,7 +12,7 @@ Signed-off-by: Honggang LI 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/include/arch/cc.h b/src/include/arch/cc.h -index 222b0c9..aa18573 100644 +index 222b0c9..10d667b 100644 --- a/src/include/arch/cc.h +++ b/src/include/arch/cc.h @@ -62,7 +62,7 @@ void alloc_memp_##name##_base(void) \ diff --git a/0034-add-accept4-and-epoll_create1.patch b/0034-add-accept4-and-epoll_create1.patch index 37594eb..d648405 100644 --- a/0034-add-accept4-and-epoll_create1.patch +++ b/0034-add-accept4-and-epoll_create1.patch @@ -23,10 +23,10 @@ index 6afb9c6..e721381 100644 CHECK_DLSYM_RET_RETURN(posix_api->epoll_wait_fn = dlsym(handle, "epoll_wait")); CHECK_DLSYM_RET_RETURN(posix_api->fork_fn = dlsym(handle, "fork")); diff --git a/src/api/sockets.c b/src/api/sockets.c -index 4d4cea1..c939899 100644 +index 129f7cc..39376a5 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -543,10 +543,11 @@ get_socket_by_fd(int fd) +@@ -583,10 +583,11 @@ get_socket_by_fd(int fd) * @param newconn the netconn for which to allocate a socket * @param accepted 1 if socket has been created by accept(), * 0 if socket has been created by socket() @@ -39,7 +39,7 @@ index 4d4cea1..c939899 100644 { int i; SYS_ARCH_DECL_PROTECT(lev); -@@ -570,12 +571,19 @@ alloc_socket(struct netconn *newconn, int accepted) +@@ -610,12 +611,19 @@ alloc_socket(struct netconn *newconn, int accepted) break; } @@ -59,7 +59,7 @@ index 4d4cea1..c939899 100644 if ((i < LWIP_SOCKET_OFFSET) || (i >= sockets_num + LWIP_SOCKET_OFFSET)) { goto err; } -@@ -721,7 +729,7 @@ free_socket(struct lwip_sock *sock, int is_tcp) +@@ -764,7 +772,7 @@ free_socket(struct lwip_sock *sock, int is_tcp) */ int @@ -68,7 +68,7 @@ index 4d4cea1..c939899 100644 { struct lwip_sock *sock, *nsock; struct netconn *newconn; -@@ -755,7 +763,7 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +@@ -797,7 +805,7 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) } LWIP_ASSERT("newconn != NULL", newconn != NULL); @@ -76,8 +76,8 @@ index 4d4cea1..c939899 100644 + newsock = alloc_socket(newconn, 1, flags); if (newsock == -1) { netconn_delete(newconn); - sock_set_errno(sock, ENFILE); -@@ -827,6 +835,12 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) + set_errno(ENFILE); +@@ -869,6 +877,12 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) return newsock; } @@ -90,7 +90,7 @@ index 4d4cea1..c939899 100644 int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) { -@@ -1823,6 +1837,10 @@ lwip_socket(int domain, int type, int protocol) +@@ -1868,6 +1882,10 @@ lwip_socket(int domain, int type, int protocol) LWIP_UNUSED_ARG(domain); /* @todo: check this */ @@ -101,7 +101,7 @@ index 4d4cea1..c939899 100644 /* create a netconn */ switch (type) { case SOCK_RAW: -@@ -1862,7 +1880,15 @@ lwip_socket(int domain, int type, int protocol) +@@ -1907,7 +1925,15 @@ lwip_socket(int domain, int type, int protocol) return -1; } @@ -119,10 +119,10 @@ index 4d4cea1..c939899 100644 if (i == -1) { netconn_delete(conn); diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h -index 4e7e671..3c5b87b 100644 +index 1d63e8f..ca5bf6e 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h -@@ -573,6 +573,7 @@ void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: destro +@@ -592,6 +592,7 @@ void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: destro #if LWIP_COMPAT_SOCKETS == 2 /* This helps code parsers/code completion by not having the COMPAT functions as defines */ #define lwip_accept accept @@ -130,7 +130,7 @@ index 4e7e671..3c5b87b 100644 #define lwip_bind bind #define lwip_shutdown shutdown #define lwip_getpeername getpeername -@@ -614,7 +615,25 @@ int fcntl(int s, int cmd, ...); +@@ -633,7 +634,25 @@ int fcntl(int s, int cmd, ...); #endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ #endif /* LWIP_COMPAT_SOCKETS == 2 */ @@ -156,7 +156,7 @@ index 4e7e671..3c5b87b 100644 int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); int lwip_shutdown(int s, int how); int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen); -@@ -661,6 +680,8 @@ int lwip_inet_pton(int af, const char *src, void *dst); +@@ -680,6 +699,8 @@ int lwip_inet_pton(int af, const char *src, void *dst); /** @ingroup socket */ #define accept(s,addr,addrlen) lwip_accept(s,addr,addrlen) /** @ingroup socket */ diff --git a/0040-add-huge-snd_buf.patch b/0040-add-huge-snd_buf.patch index 73fa142..4dcf653 100644 --- a/0040-add-huge-snd_buf.patch +++ b/0040-add-huge-snd_buf.patch @@ -1,19 +1,34 @@ -diff -Nur lwip-2.1.3-org/src/core/init.c lwip-2.1.3/src/core/init.c ---- lwip-2.1.3-org/src/core/init.c 2022-12-06 14:40:45.280000000 +0000 -+++ lwip-2.1.3/src/core/init.c 2022-12-06 14:41:01.452000000 +0000 -@@ -306,7 +306,7 @@ - #if TCP_SNDLOWAT >= TCP_SND_BUF - #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +From d9e656c6ca48367fdc174b00c64d6f3fb0584a38 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 5 Feb 2024 15:09:14 +0800 +Subject: [PATCH] add huge snd_buf + +--- + src/core/init.c | 2 +- + src/core/pbuf.c | 9 ++++++--- + src/include/lwip/opt.h | 2 +- + src/include/lwip/pbuf.h | 2 +- + src/include/lwipopts.h | 2 +- + 5 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/core/init.c b/src/core/init.c +index 5b60ed8..6841857 100644 +--- a/src/core/init.c ++++ b/src/core/init.c +@@ -312,7 +312,7 @@ PACK_STRUCT_END + #if TCP_MSS >= ((16 * 1024) - 1) + #error "lwip_sanity_check: WARNING: TCP_MSS must be <= 16382 to prevent u16_t underflow in TCP_SNDLOWAT calculation!" #endif -#if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS)) +#if TCP_SNDLOWAT >= (0xFFFFFFFF - (4 * TCP_MSS)) #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!" #endif #if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN -diff -Nur lwip-2.1.3-org/src/core/pbuf.c lwip-2.1.3/src/core/pbuf.c ---- lwip-2.1.3-org/src/core/pbuf.c 2022-12-06 14:40:45.280000000 +0000 -+++ lwip-2.1.3/src/core/pbuf.c 2022-12-06 14:46:04.860000000 +0000 -@@ -869,13 +869,13 @@ +diff --git a/src/core/pbuf.c b/src/core/pbuf.c +index 69a52b6..bea0e81 100644 +--- a/src/core/pbuf.c ++++ b/src/core/pbuf.c +@@ -871,13 +871,13 @@ pbuf_cat(struct pbuf *h, struct pbuf *t) /* proceed to last pbuf of chain */ for (p = h; p->next != NULL; p = p->next) { /* add total length of second chain to all totals of first chain */ @@ -29,7 +44,7 @@ diff -Nur lwip-2.1.3-org/src/core/pbuf.c lwip-2.1.3/src/core/pbuf.c /* chain last pbuf of head (p) with first of tail (t) */ p->next = t; /* p->next now references t, but the caller will drop its reference to t, -@@ -1181,7 +1181,7 @@ +@@ -1178,7 +1178,7 @@ void pbuf_split_64k(struct pbuf *p, struct pbuf **rest) if (r != NULL) { /* Update the tot_len field in the first part */ for (i = p; i != NULL; i = i->next) { @@ -38,7 +53,7 @@ diff -Nur lwip-2.1.3-org/src/core/pbuf.c lwip-2.1.3/src/core/pbuf.c LWIP_ASSERT("tot_len/len mismatch in last pbuf", (i->next != NULL) || (i->tot_len == i->len)); } -@@ -1192,6 +1192,9 @@ +@@ -1189,6 +1189,9 @@ void pbuf_split_64k(struct pbuf *p, struct pbuf **rest) /* tot_len field in rest does not need modifications */ /* reference counters do not need modifications */ *rest = r; @@ -48,10 +63,11 @@ diff -Nur lwip-2.1.3-org/src/core/pbuf.c lwip-2.1.3/src/core/pbuf.c } } } -diff -Nur lwip-2.1.3-org/src/include/lwip/opt.h lwip-2.1.3/src/include/lwip/opt.h ---- lwip-2.1.3-org/src/include/lwip/opt.h 2022-12-06 14:40:45.292000000 +0000 -+++ lwip-2.1.3/src/include/lwip/opt.h 2022-12-06 14:41:01.456000000 +0000 -@@ -1482,7 +1482,7 @@ +diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h +index b738460..570d2de 100644 +--- a/src/include/lwip/opt.h ++++ b/src/include/lwip/opt.h +@@ -1533,7 +1533,7 @@ * send window while having a small receive window only. */ #if !defined LWIP_WND_SCALE || defined __DOXYGEN__ @@ -60,10 +76,11 @@ diff -Nur lwip-2.1.3-org/src/include/lwip/opt.h lwip-2.1.3/src/include/lwip/opt. #define TCP_RCV_SCALE 0 #endif -diff -Nur lwip-2.1.3-org/src/include/lwip/pbuf.h lwip-2.1.3/src/include/lwip/pbuf.h ---- lwip-2.1.3-org/src/include/lwip/pbuf.h 2022-12-06 14:40:45.284000000 +0000 -+++ lwip-2.1.3/src/include/lwip/pbuf.h 2022-12-06 14:46:36.720000000 +0000 -@@ -197,7 +197,7 @@ +diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h +index b362007..60d8d1a 100644 +--- a/src/include/lwip/pbuf.h ++++ b/src/include/lwip/pbuf.h +@@ -197,7 +197,7 @@ struct pbuf { * For non-queue packet chains this is the invariant: * p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ @@ -72,9 +89,10 @@ diff -Nur lwip-2.1.3-org/src/include/lwip/pbuf.h lwip-2.1.3/src/include/lwip/pbu /** length of this buffer */ u16_t len; -diff -Nur lwip-2.1.3-org/src/include/lwipopts.h lwip-2.1.3/src/include/lwipopts.h ---- lwip-2.1.3-org/src/include/lwipopts.h 2022-12-06 14:40:45.292000000 +0000 -+++ lwip-2.1.3/src/include/lwipopts.h 2022-12-06 14:41:01.456000000 +0000 +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index 7c819d0..d7b9635 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h @@ -97,7 +97,7 @@ #define TCP_WND (40 * TCP_MSS) @@ -84,3 +102,6 @@ diff -Nur lwip-2.1.3-org/src/include/lwipopts.h lwip-2.1.3/src/include/lwipopts. #define TCP_SND_QUEUELEN (8191) +-- +2.33.0 + diff --git a/0041-optimite-pcb-list-limit-send-size-and-ack-now.patch b/0041-optimite-pcb-list-limit-send-size-and-ack-now.patch index 2c47b15..ffae567 100644 --- a/0041-optimite-pcb-list-limit-send-size-and-ack-now.patch +++ b/0041-optimite-pcb-list-limit-send-size-and-ack-now.patch @@ -13,10 +13,10 @@ Subject: [PATCH] optimite pcb-list limit , send size and ack now 6 files changed, 83 insertions(+), 43 deletions(-) diff --git a/src/core/tcp.c b/src/core/tcp.c -index 51ada38..cb08f95 100644 +index 699dda4..54d9ded 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c -@@ -2297,6 +2297,7 @@ tcp_pcb_purge(struct tcp_pcb *pcb) +@@ -2303,6 +2303,7 @@ tcp_pcb_purge(struct tcp_pcb *pcb) tcp_segs_free(pcb->unsent); tcp_segs_free(pcb->unacked); pcb->unacked = pcb->unsent = NULL; @@ -25,10 +25,10 @@ index 51ada38..cb08f95 100644 pcb->unsent_oversize = 0; #endif /* TCP_OVERSIZE */ diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 2d6cb6a..78954bd 100644 +index fa574ff..ef95238 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c -@@ -976,8 +976,14 @@ tcp_process(struct tcp_pcb *pcb) +@@ -979,8 +979,14 @@ tcp_process(struct tcp_pcb *pcb) rseg = pcb->unsent; LWIP_ASSERT("no segment to free", rseg != NULL); pcb->unsent = rseg->next; @@ -43,7 +43,7 @@ index 2d6cb6a..78954bd 100644 } tcp_seg_free(rseg); -@@ -1393,6 +1399,8 @@ tcp_receive(struct tcp_pcb *pcb) +@@ -1389,6 +1395,8 @@ tcp_receive(struct tcp_pcb *pcb) /* Remove segment from the unacknowledged list if the incoming ACK acknowledges them. */ pcb->unacked = tcp_free_acked_segments(pcb, pcb->unacked, "unacked", pcb->unsent); @@ -52,7 +52,7 @@ index 2d6cb6a..78954bd 100644 /* We go through the ->unsent list to see if any of the segments on the list are acknowledged by the ACK. This may seem strange since an "unsent" segment shouldn't be acked. The -@@ -1400,6 +1408,8 @@ tcp_receive(struct tcp_pcb *pcb) +@@ -1396,6 +1404,8 @@ tcp_receive(struct tcp_pcb *pcb) ->unsent list after a retransmission, so these segments may in fact have been sent once. */ pcb->unsent = tcp_free_acked_segments(pcb, pcb->unsent, "unsent", pcb->unacked); @@ -61,7 +61,7 @@ index 2d6cb6a..78954bd 100644 /* If there's nothing left to acknowledge, stop the retransmit timer, otherwise reset it to start again */ -@@ -1736,7 +1746,11 @@ tcp_receive(struct tcp_pcb *pcb) +@@ -1732,7 +1742,11 @@ tcp_receive(struct tcp_pcb *pcb) /* Acknowledge the segment(s). */ @@ -75,10 +75,10 @@ index 2d6cb6a..78954bd 100644 #if LWIP_TCP_SACK_OUT if (LWIP_TCP_SACK_VALID(pcb, 0)) { diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c -index f53750b..55053d8 100644 +index b1d9f23..342f4aa 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c -@@ -631,11 +631,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -634,11 +634,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) #endif /* TCP_OVERSIZE */ } #else /* USE_LIBOS */ @@ -91,7 +91,7 @@ index f53750b..55053d8 100644 #endif /* USE_LIBOS */ /* -@@ -851,6 +847,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -854,6 +850,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) * Finally update the pcb state. */ #if USE_LIBOS @@ -101,7 +101,7 @@ index f53750b..55053d8 100644 pcb->snd_lbb += pos; pcb->snd_buf -= pos; #else -@@ -1050,6 +1049,8 @@ tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split) +@@ -1053,6 +1052,8 @@ tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split) /* Finally insert remainder into queue after split (which stays head) */ seg->next = useg->next; useg->next = seg; @@ -110,7 +110,7 @@ index f53750b..55053d8 100644 #if TCP_OVERSIZE /* If remainder is last segment on the unsent, ensure we clear the oversize amount -@@ -1086,9 +1087,7 @@ tcp_send_fin(struct tcp_pcb *pcb) +@@ -1089,9 +1090,7 @@ tcp_send_fin(struct tcp_pcb *pcb) /* first, try to add the fin to the last unsent segment */ if (pcb->unsent != NULL) { @@ -121,7 +121,7 @@ index f53750b..55053d8 100644 if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) { /* no SYN/FIN/RST flag in the header, we can add the FIN flag */ -@@ -1182,10 +1181,10 @@ tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) +@@ -1185,10 +1184,10 @@ tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) if (pcb->unsent == NULL) { pcb->unsent = seg; } else { @@ -134,7 +134,7 @@ index f53750b..55053d8 100644 #if TCP_OVERSIZE /* The new unsent tail has no space */ pcb->unsent_oversize = 0; -@@ -1314,6 +1313,7 @@ static struct tcp_seg *tcp_output_over(struct tcp_pcb *pcb, struct tcp_seg *seg, +@@ -1317,6 +1316,7 @@ static struct tcp_seg *tcp_output_over(struct tcp_pcb *pcb, struct tcp_seg *seg, seg->next = NULL; if (useg == NULL) { pcb->unacked = seg; @@ -142,7 +142,7 @@ index f53750b..55053d8 100644 useg = seg; } else { if (TCP_SEQ_LT(lwip_ntohl(seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) { -@@ -1329,6 +1329,7 @@ static struct tcp_seg *tcp_output_over(struct tcp_pcb *pcb, struct tcp_seg *seg, +@@ -1332,6 +1332,7 @@ static struct tcp_seg *tcp_output_over(struct tcp_pcb *pcb, struct tcp_seg *seg, /* add segment to tail of unacked list */ useg->next = seg; useg = seg; @@ -150,7 +150,7 @@ index f53750b..55053d8 100644 } } } else { -@@ -1460,15 +1461,14 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1463,15 +1464,14 @@ tcp_output(struct tcp_pcb *pcb) pcb->persist_backoff = 0; /* useg should point to last segment on unacked queue */ @@ -170,7 +170,7 @@ index f53750b..55053d8 100644 /** * 1)遍历unsent队列,找到所有的待发送seg. 将seg的buf串起来 * 2) 生成新的seg, 调用tcp_output_segment, 新的seg释放掉 -@@ -1510,6 +1510,7 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1513,6 +1513,7 @@ tcp_output(struct tcp_pcb *pcb) pre_pbuf->next = seg->p; } @@ -178,7 +178,7 @@ index f53750b..55053d8 100644 pre_pbuf = seg->p; next_seqno = seg_seqno + TCP_TCPLEN(seg); seg = seg->next; -@@ -1519,8 +1520,11 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1522,8 +1523,11 @@ tcp_output(struct tcp_pcb *pcb) if (first_pbuf == NULL) { err = tcp_output_seg(pcb, seg, netif, next_seqno + seg->len); @@ -191,7 +191,7 @@ index f53750b..55053d8 100644 pcb->unsent = seg->next; useg = tcp_output_over(pcb, seg, useg); seg = pcb->unsent; -@@ -1545,7 +1549,7 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1548,7 +1552,7 @@ tcp_output(struct tcp_pcb *pcb) } else #endif { @@ -200,7 +200,7 @@ index f53750b..55053d8 100644 lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { LWIP_ASSERT("RST not expected here!", (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0); -@@ -1560,6 +1564,7 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1563,6 +1567,7 @@ tcp_output(struct tcp_pcb *pcb) ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)) { break; } @@ -208,7 +208,7 @@ index f53750b..55053d8 100644 #if TCP_CWND_DEBUG LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n", pcb->snd_wnd, pcb->cwnd, wnd, -@@ -1577,6 +1582,8 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1580,6 +1585,8 @@ tcp_output(struct tcp_pcb *pcb) if (err != ERR_OK) { /* segment could not be sent, for whatever reason */ tcp_set_flags(pcb, TF_NAGLEMEMERR); @@ -217,7 +217,7 @@ index f53750b..55053d8 100644 return err; } #if TCP_OVERSIZE_DBGCHECK -@@ -1596,6 +1603,7 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1599,6 +1606,7 @@ tcp_output(struct tcp_pcb *pcb) /* unacked list is empty? */ if (pcb->unacked == NULL) { pcb->unacked = seg; @@ -225,7 +225,7 @@ index f53750b..55053d8 100644 useg = seg; /* unacked list is not empty? */ } else { -@@ -1615,6 +1623,7 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1618,6 +1626,7 @@ tcp_output(struct tcp_pcb *pcb) /* add segment to tail of unacked list */ useg->next = seg; useg = useg->next; @@ -233,7 +233,7 @@ index f53750b..55053d8 100644 } } /* do not queue empty segments on the unacked list */ -@@ -1632,6 +1641,8 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1635,6 +1644,8 @@ tcp_output(struct tcp_pcb *pcb) #endif /* TCP_OVERSIZE */ output_done: @@ -242,7 +242,7 @@ index f53750b..55053d8 100644 tcp_clear_flags(pcb, TF_NAGLEMEMERR); return ERR_OK; } -@@ -1932,9 +1943,13 @@ tcp_rexmit_rto_prepare(struct tcp_pcb *pcb) +@@ -1935,9 +1946,13 @@ tcp_rexmit_rto_prepare(struct tcp_pcb *pcb) } #endif /* TCP_OVERSIZE_DBGCHECK */ /* unsent queue is the concatenated queue (of unacked, unsent) */ @@ -256,7 +256,7 @@ index f53750b..55053d8 100644 /* Mark RTO in-progress */ tcp_set_flags(pcb, TF_RTO); -@@ -2004,32 +2019,42 @@ tcp_rexmit(struct tcp_pcb *pcb) +@@ -2007,32 +2022,42 @@ tcp_rexmit(struct tcp_pcb *pcb) } seg = pcb->unacked; @@ -320,8 +320,8 @@ index f53750b..55053d8 100644 if (pcb->nrtx < 0xFF) { ++pcb->nrtx; } -@@ -2207,7 +2232,7 @@ tcp_output_control_segment(const struct tcp_pcb *pcb, struct pbuf *p, - struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload; +@@ -2227,7 +2252,7 @@ tcp_output_control_segment_netif(const struct tcp_pcb *pcb, struct pbuf *p, + struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload; #if CHECKSUM_GEN_TCP_HW if (get_eth_params_tx_ol() & DEV_TX_OFFLOAD_TCP_CKSUM) { - tcph_cksum_set(p, TCP_HLEN); @@ -330,10 +330,10 @@ index f53750b..55053d8 100644 } else { tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h -index 8294cdd..83e7e93 100644 +index 570d2de..39fd224 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h -@@ -1281,7 +1281,7 @@ +@@ -1323,7 +1323,7 @@ * LWIP_TCP_SACK_OUT==1: TCP will support sending selective acknowledgements (SACKs). */ #if !defined LWIP_TCP_SACK_OUT || defined __DOXYGEN__ @@ -343,7 +343,7 @@ index 8294cdd..83e7e93 100644 /** diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h -index b36bf33..b0ae02c 100644 +index a19fb0e..9ebdbf2 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -356,7 +356,9 @@ struct tcp_pcb { diff --git a/0044-skip-unnecessary-tcp_route.patch b/0044-skip-unnecessary-tcp_route.patch index b93b7d5..bffca67 100644 --- a/0044-skip-unnecessary-tcp_route.patch +++ b/0044-skip-unnecessary-tcp_route.patch @@ -11,10 +11,10 @@ Subject: [PATCH] skip unnecessary tcp_route 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/core/tcp.c b/src/core/tcp.c -index 252f27f..abfcc00 100644 +index 54d9ded..b2bee67 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c -@@ -2294,6 +2294,7 @@ tcp_pcb_purge(struct tcp_pcb *pcb) +@@ -2304,6 +2304,7 @@ tcp_pcb_purge(struct tcp_pcb *pcb) tcp_segs_free(pcb->unacked); pcb->unacked = pcb->unsent = NULL; pcb->last_unacked = pcb->last_unsent = NULL; @@ -23,10 +23,10 @@ index 252f27f..abfcc00 100644 pcb->unsent_oversize = 0; #endif /* TCP_OVERSIZE */ diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c -index 25aeb23..1c5734b 100644 +index e862f9e..99f8e66 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c -@@ -1425,7 +1425,12 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1428,7 +1428,12 @@ tcp_output(struct tcp_pcb *pcb) lwip_ntohl(seg->tcphdr->seqno), pcb->lastack)); } @@ -40,7 +40,7 @@ index 25aeb23..1c5734b 100644 if (netif == NULL) { return ERR_RTE; } -@@ -2220,7 +2225,7 @@ tcp_output_fill_options(const struct tcp_pcb *pcb, struct pbuf *p, u8_t optflags +@@ -2223,14 +2228,21 @@ tcp_output_fill_options(const struct tcp_pcb *pcb, struct pbuf *p, u8_t optflags * header checksum and calling ip_output_if while handling netif hints and stats. */ static err_t @@ -48,8 +48,7 @@ index 25aeb23..1c5734b 100644 +tcp_output_control_segment(struct tcp_pcb *pcb, struct pbuf *p, const ip_addr_t *src, const ip_addr_t *dst) { - err_t err; -@@ -2228,7 +2233,14 @@ tcp_output_control_segment(const struct tcp_pcb *pcb, struct pbuf *p, + struct netif *netif; LWIP_ASSERT("tcp_output_control_segment: invalid pbuf", p != NULL); @@ -63,19 +62,10 @@ index 25aeb23..1c5734b 100644 + netif = pcb->pcb_if; + } if (netif == NULL) { - err = ERR_RTE; - } else { -@@ -2318,7 +2330,7 @@ tcp_rst(const struct tcp_pcb *pcb, u32_t seqno, u32_t ackno, - - MIB2_STATS_INC(mib2.tcpoutrsts); - -- tcp_output_control_segment(pcb, p, local_ip, remote_ip); -+ tcp_output_control_segment((struct tcp_pcb*)pcb, p, local_ip, remote_ip); - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); - } - + pbuf_free(p); + return ERR_RTE; diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h -index b0ae02c..2a61776 100644 +index 9ebdbf2..07b7dc0 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -408,6 +408,7 @@ struct tcp_pcb { @@ -87,10 +77,10 @@ index b0ae02c..2a61776 100644 #if TCP_PCB_HASH diff --git a/src/include/lwipsock.h b/src/include/lwipsock.h -index 62e5bf1..ec4d78c 100644 +index bf0d753..3cf0062 100644 --- a/src/include/lwipsock.h +++ b/src/include/lwipsock.h -@@ -111,6 +111,7 @@ struct lwip_sock { +@@ -110,6 +110,7 @@ struct lwip_sock { /* stack thread all use */ struct list_node recv_list; struct list_node send_list; diff --git a/0046-add-dataack-when-recv-too-many-acks-with-data.patch b/0046-add-dataack-when-recv-too-many-acks-with-data.patch deleted file mode 100644 index 70131e5..0000000 --- a/0046-add-dataack-when-recv-too-many-acks-with-data.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 1aa27395a4c4b73b6db472c4ae75ed91637a11bf Mon Sep 17 00:00:00 2001 -From: kircher -Date: Wed, 21 Dec 2022 17:50:50 +0800 -Subject: [PATCH] add dataack when recv too many acks with data - ---- - src/core/tcp_in.c | 22 ++++++++++++++++++++++ - src/include/lwip/tcp.h | 1 + - src/include/lwipopts.h | 2 ++ - 3 files changed, 25 insertions(+) - -diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 78954bd..35ec6d9 100644 ---- a/src/core/tcp_in.c -+++ b/src/core/tcp_in.c -@@ -1260,6 +1260,7 @@ tcp_receive(struct tcp_pcb *pcb) - s16_t m; - u32_t right_wnd_edge; - int found_dupack = 0; -+ int found_dataack = 0; - - LWIP_ASSERT("tcp_receive: invalid pcb", pcb != NULL); - LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED); -@@ -1337,11 +1338,31 @@ tcp_receive(struct tcp_pcb *pcb) - } - } - } -+ /* fast rexmit when receive too many acks with data */ -+ if (TCP_SEQ_LT(ackno + 1, pcb->snd_nxt)) { -+ if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) { -+ if (pcb->rtime >= 0) { -+ if (pcb->lastack == ackno) { -+ found_dataack = 1; -+ ++pcb->dataacks; -+ if (pcb->dataacks > MAX_DATA_ACK_NUM) { -+ if (tcp_rexmit(pcb) == ERR_OK) { -+ pcb->rtime = 0; -+ pcb->dataacks = 0; -+ } -+ } -+ } -+ } -+ } -+ } - /* If Clause (1) or more is true, but not a duplicate ack, reset - * count of consecutive duplicate acks */ - if (!found_dupack) { - pcb->dupacks = 0; - } -+ if (!found_dataack) { -+ pcb->dataacks = 0; -+ } - } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) { - /* We come here when the ACK acknowledges new data. */ - tcpwnd_size_t acked; -@@ -1367,6 +1388,7 @@ tcp_receive(struct tcp_pcb *pcb) - /* Reset the fast retransmit variables. */ - pcb->dupacks = 0; - pcb->lastack = ackno; -+ pcb->dataacks = 0; - - /* Update the congestion control variables (cwnd and - ssthresh). */ -diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h -index 2a61776..97cb882 100644 ---- a/src/include/lwip/tcp.h -+++ b/src/include/lwip/tcp.h -@@ -326,6 +326,7 @@ struct tcp_pcb { - - /* fast retransmit/recovery */ - u8_t dupacks; -+ u32_t dataacks; - u32_t lastack; /* Highest acknowledged seqno. */ - - /* congestion avoidance/control variables */ -diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index 907c630..405cf11 100644 ---- a/src/include/lwipopts.h -+++ b/src/include/lwipopts.h -@@ -177,6 +177,8 @@ - - #define MIN_TSO_SEG_LEN 256 - -+#define MAX_DATA_ACK_NUM 256 -+ - /* --------------------------------------- - * ------- NIC offloads -------- - * --------------------------------------- --- -2.33.0 - diff --git a/0050-lwip-reuse-ip-port.patch b/0050-lwip-reuse-ip-port.patch index 08cdcdd..a14f048 100644 --- a/0050-lwip-reuse-ip-port.patch +++ b/0050-lwip-reuse-ip-port.patch @@ -13,7 +13,7 @@ Subject: [PATCH] lwip reuse ip port 6 files changed, 104 insertions(+), 3 deletions(-) diff --git a/src/core/tcp.c b/src/core/tcp.c -index f75d214..3171c5e 100644 +index b2bee67..2cc1174 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -111,6 +111,7 @@ @@ -85,10 +85,10 @@ index f75d214..3171c5e 100644 + lpcb->master_lpcb = conn->is_master_fd; +#endif + - #if LWIP_IPV4 && LWIP_IPV6 - IP_SET_TYPE_VAL(lpcb->remote_ip, pcb->local_ip.type); - #endif /* LWIP_IPV4 && LWIP_IPV6 */ -@@ -979,7 +1005,15 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) + #if LWIP_VLAN_PCP + lpcb->netif_hints.tci = pcb->netif_hints.tci; + #endif /* LWIP_VLAN_PCP */ +@@ -982,7 +1008,15 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) lpcb->accepts_pending = 0; tcp_backlog_set(lpcb, backlog); #endif /* TCP_LISTEN_BACKLOG */ @@ -106,7 +106,7 @@ index f75d214..3171c5e 100644 done: if (err != NULL) { diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 35ec6d9..9f5c34a 100644 +index ef95238..77dd235 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -356,6 +356,9 @@ tcp_input(struct pbuf *p, struct netif *inp) @@ -121,7 +121,7 @@ index 35ec6d9..9f5c34a 100644 prev = NULL; @@ -379,6 +382,30 @@ tcp_input(struct pbuf *p, struct netif *inp) } else if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) { - if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) { + if (ip_addr_eq(&lpcb->local_ip, ip_current_dest_addr())) { /* found an exact match */ +#if REUSE_IPPORT + // check master fd @@ -164,7 +164,7 @@ index 35ec6d9..9f5c34a 100644 pbuf_free(p); return; diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h -index 6dec8c0..430a7a0 100644 +index 55fc413..d12312c 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -318,6 +318,10 @@ struct netconn { @@ -179,7 +179,7 @@ index 6dec8c0..430a7a0 100644 /** This vector type is passed to @ref netconn_write_vectors_partly to send diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h -index b242428..97f799e 100644 +index 783acf5..02481da 100644 --- a/src/include/lwip/priv/tcp_priv.h +++ b/src/include/lwip/priv/tcp_priv.h @@ -353,6 +353,15 @@ static inline int vdev_reg_done(enum reg_ring_type reg_type, const struct tcp_pc @@ -216,7 +216,7 @@ index b242428..97f799e 100644 do { \ hlist_del_init(&(npcb)->tcp_node); \ diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h -index 0b65b01..312320b 100644 +index 9ebdbf2..c5e4654 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -252,6 +252,14 @@ struct tcp_pcb_listen { @@ -235,7 +235,7 @@ index 0b65b01..312320b 100644 diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index fedded9..be58ec3 100644 +index 97e96ab..f8b3294 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h @@ -143,6 +143,10 @@ diff --git a/0052-lwip_fnctl-only-support-F_SETFL-F_GETFL.patch b/0052-lwip_fnctl-only-support-F_SETFL-F_GETFL.patch index 02af140..af6565c 100644 --- a/0052-lwip_fnctl-only-support-F_SETFL-F_GETFL.patch +++ b/0052-lwip_fnctl-only-support-F_SETFL-F_GETFL.patch @@ -9,18 +9,18 @@ Subject: [PATCH] lwip_cnctl only support F_SETFL,F_GETFL, other opt return 0 1 file changed, 5 insertions(+) diff --git a/src/api/sockets.c b/src/api/sockets.c -index 9b3f514..2cb6f22 100644 +index 39376a5..e99bba7 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -4107,7 +4107,12 @@ lwip_fcntl(int s, int cmd, int val) +@@ -4149,7 +4149,12 @@ lwip_fcntl(int s, int cmd, int val) break; default: LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); +#if USE_LIBOS -+ sock_set_errno(sock, 0); /* not yet implemented, but we return 0 for compatilbe with app */ ++ sock_errno(sock, 0); /* not yet implemented, but we return 0 for compatilbe with app */ + ret = 0; +#else - sock_set_errno(sock, ENOSYS); /* not yet implemented */ + set_errno(ENOSYS); /* not yet implemented */ +#endif break; } diff --git a/0053-cleancode-improve-lwipopts.h-readability.patch b/0053-cleancode-improve-lwipopts.h-readability.patch index 6996746..d8b0b99 100644 --- a/0053-cleancode-improve-lwipopts.h-readability.patch +++ b/0053-cleancode-improve-lwipopts.h-readability.patch @@ -38,7 +38,7 @@ Signed-off-by: Lemmy Huang 30 files changed, 339 insertions(+), 317 deletions(-) diff --git a/src/api/api_msg.c b/src/api/api_msg.c -index 3a4a473..1840c9d 100644 +index 1162f90..5a2e689 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -54,7 +54,7 @@ @@ -50,7 +50,7 @@ index 3a4a473..1840c9d 100644 #include "lwip/sockets.h" #include "lwipsock.h" #include "posix_api.h" -@@ -341,7 +341,7 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +@@ -344,7 +344,7 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) #if LWIP_SO_RCVBUF SYS_ARCH_INC(conn->recv_avail, len); #endif /* LWIP_SO_RCVBUF */ @@ -59,7 +59,7 @@ index 3a4a473..1840c9d 100644 add_recv_list(conn->socket); LWIP_UNUSED_ARG(len); #else -@@ -477,7 +477,7 @@ err_tcp(void *arg, err_t err) +@@ -480,7 +480,7 @@ err_tcp(void *arg, err_t err) if (NETCONN_MBOX_VALID(conn, &conn->recvmbox)) { /* use trypost to prevent deadlock */ sys_mbox_trypost(&conn->recvmbox, mbox_msg); @@ -68,7 +68,7 @@ index 3a4a473..1840c9d 100644 add_recv_list(conn->socket); #endif } -@@ -609,7 +609,7 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) +@@ -612,7 +612,7 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); } @@ -77,7 +77,7 @@ index 3a4a473..1840c9d 100644 LWIP_DEBUGF(API_MSG_DEBUG, ("libos incoming connection established\n")); SET_CONN_TYPE_LIBOS(newconn); #endif -@@ -1333,7 +1333,7 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) +@@ -1334,7 +1334,7 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) return ERR_VAL; } @@ -86,7 +86,7 @@ index 3a4a473..1840c9d 100644 gazelle_connected_callback(conn); #endif -@@ -1738,7 +1738,7 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) +@@ -1739,7 +1739,7 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) } else { write_more = 0; } @@ -96,7 +96,7 @@ index 3a4a473..1840c9d 100644 LWIP_UNUSED_ARG(dataptr); write_more = 0; diff --git a/src/api/sockets.c b/src/api/sockets.c -index 2cb6f22..356e345 100644 +index de6c701..e525c9d 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -62,7 +62,7 @@ @@ -108,8 +108,8 @@ index 2cb6f22..356e345 100644 #include #include "lwipsock.h" #include "posix_api.h" -@@ -92,7 +92,7 @@ - #define API_SELECT_CB_VAR_FREE(name) API_VAR_FREE(MEMP_SELECT_CB, name) +@@ -137,7 +137,7 @@ + #endif /* LWIP_SOCKET_HAVE_SA_LEN */ #if LWIP_IPV4 -#if USE_LIBOS @@ -117,7 +117,7 @@ index 2cb6f22..356e345 100644 #define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \ (sin)->sin_family = AF_INET; \ (sin)->sin_port = lwip_htons((port)); \ -@@ -105,7 +105,7 @@ +@@ -150,7 +150,7 @@ (sin)->sin_port = lwip_htons((port)); \ inet_addr_from_ip4addr(&(sin)->sin_addr, ipaddr); \ memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0) @@ -126,7 +126,7 @@ index 2cb6f22..356e345 100644 #define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipaddr, port) do { \ inet_addr_to_ip4addr(ip_2_ip4(ipaddr), &((sin)->sin_addr)); \ (port) = lwip_ntohs((sin)->sin_port); }while(0) -@@ -271,12 +271,12 @@ static void lwip_socket_drop_registered_mld6_memberships(int s); +@@ -316,12 +316,12 @@ static void lwip_socket_drop_registered_mld6_memberships(int s); #endif /* LWIP_IPV6_MLD */ /** The global array of available sockets */ @@ -141,7 +141,7 @@ index 2cb6f22..356e345 100644 #if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL #if LWIP_TCPIP_CORE_LOCKING -@@ -431,11 +431,11 @@ tryget_socket_unconn_nouse(int fd) +@@ -471,11 +471,11 @@ tryget_socket_unconn_nouse(int fd) { int s = fd - LWIP_SOCKET_OFFSET; @@ -155,7 +155,7 @@ index 2cb6f22..356e345 100644 { LWIP_DEBUGF(SOCKETS_DEBUG, ("tryget_socket_unconn(%d): invalid\n", fd)); return NULL; -@@ -500,13 +500,13 @@ tryget_socket(int fd) +@@ -540,13 +540,13 @@ tryget_socket(int fd) * @param fd externally used socket index * @return struct lwip_sock for the socket or NULL if not found */ @@ -171,7 +171,7 @@ index 2cb6f22..356e345 100644 { struct lwip_sock *sock = tryget_socket(fd); if (!sock) { -@@ -519,7 +519,7 @@ get_socket(int fd) +@@ -559,7 +559,7 @@ get_socket(int fd) return sock; } @@ -180,7 +180,7 @@ index 2cb6f22..356e345 100644 /** * Map a externally used socket index to the internal socket representation. * -@@ -535,7 +535,7 @@ get_socket_by_fd(int fd) +@@ -575,7 +575,7 @@ get_socket_by_fd(int fd) } return &sockets[fd - LWIP_SOCKET_OFFSET]; } @@ -189,7 +189,7 @@ index 2cb6f22..356e345 100644 /** * Allocate a new socket for a given netconn. -@@ -553,7 +553,7 @@ alloc_socket(struct netconn *newconn, int accepted, int flags) +@@ -593,7 +593,7 @@ alloc_socket(struct netconn *newconn, int accepted, int flags) SYS_ARCH_DECL_PROTECT(lev); LWIP_UNUSED_ARG(accepted); @@ -198,7 +198,7 @@ index 2cb6f22..356e345 100644 int type, protocol = 0, domain = AF_INET; switch (NETCONNTYPE_GROUP(newconn->type)) { case NETCONN_RAW: -@@ -615,7 +615,7 @@ err: +@@ -655,7 +655,7 @@ err: posix_api->close_fn(i); SYS_ARCH_UNPROTECT(lev); return -1; @@ -207,7 +207,7 @@ index 2cb6f22..356e345 100644 /* allocate a new socket identifier */ for (i = 0; i < NUM_SOCKETS; ++i) { -@@ -649,7 +649,7 @@ err: +@@ -689,7 +689,7 @@ err: } return -1; @@ -216,7 +216,7 @@ index 2cb6f22..356e345 100644 } /** Free a socket (under lock) -@@ -773,12 +773,12 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) +@@ -812,12 +812,12 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) done_socket(sock); return -1; } @@ -231,14 +231,14 @@ index 2cb6f22..356e345 100644 nsock = &sockets[newsock - LWIP_SOCKET_OFFSET]; /* See event_callback: If data comes in right away after an accept, even -@@ -816,13 +816,13 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) +@@ -855,13 +855,13 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) } IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port); -#if !USE_LIBOS +#if !GAZELLE_ENABLE - if (*addrlen > tempaddr.sa.sa_len) { - *addrlen = tempaddr.sa.sa_len; + if (*addrlen > IPADDR_SOCKADDR_GET_LEN(&tempaddr)) { + *addrlen = IPADDR_SOCKADDR_GET_LEN(&tempaddr); } #else *addrlen = LWIP_MIN(*addrlen, sizeof(tempaddr)); @@ -247,7 +247,7 @@ index 2cb6f22..356e345 100644 MEMCPY(addr, &tempaddr, *addrlen); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); -@@ -993,10 +993,10 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) +@@ -1030,10 +1030,10 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) return -1; } @@ -259,8 +259,8 @@ index 2cb6f22..356e345 100644 +#endif /* GAZELLE_ENABLE */ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); - sock_set_errno(sock, 0); -@@ -1065,7 +1065,7 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) + set_errno(0); +@@ -1102,7 +1102,7 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) apiflags |= NETCONN_DONTBLOCK; } @@ -269,9 +269,9 @@ index 2cb6f22..356e345 100644 do { struct pbuf *p; err_t err; -@@ -1146,13 +1146,13 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) +@@ -1182,13 +1182,13 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) + /* @todo: do we need to support peeking more than one pbuf? */ } while ((recv_left > 0) && !(flags & MSG_PEEK)); - lwip_recv_tcp_done: -#else /* USE_LIBOS */ +#else /* GAZELLE_ENABLE */ @@ -285,16 +285,16 @@ index 2cb6f22..356e345 100644 if (apiflags & NETCONN_NOAUTORCVD) { if ((recvd > 0) && !(flags & MSG_PEEK)) { /* ensure window update after copying all data */ -@@ -1188,7 +1188,7 @@ lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port, +@@ -1223,7 +1223,7 @@ lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port, #endif /* LWIP_IPV4 && LWIP_IPV6 */ IPADDR_PORT_TO_SOCKADDR(&saddr, fromaddr, port); -#if !USE_LIBOS +#if !GAZELLE_ENABLE - if (*fromlen < saddr.sa.sa_len) { + if (*fromlen < IPADDR_SOCKADDR_GET_LEN(&saddr)) { truncated = 1; - } else if (*fromlen > saddr.sa.sa_len) { -@@ -2692,7 +2692,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) + } else if (*fromlen > IPADDR_SOCKADDR_GET_LEN(&saddr)) { +@@ -2725,7 +2725,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) if (sock->rcvevent > 1) { check_waiters = 0; } @@ -303,7 +303,7 @@ index 2cb6f22..356e345 100644 if (conn->acceptmbox != NULL && !sys_mbox_empty(conn->acceptmbox)) { add_sock_event(sock, POLLIN); } -@@ -2714,7 +2714,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +@@ -2747,7 +2747,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) break; case NETCONN_EVT_ERROR: sock->errevent = 1; @@ -312,16 +312,16 @@ index 2cb6f22..356e345 100644 add_sock_event(sock, EPOLLERR); #endif break; -@@ -2911,7 +2911,7 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) +@@ -2944,7 +2944,7 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) ip_addr_debug_print_val(SOCKETS_DEBUG, naddr); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port)); -#if !USE_LIBOS +#if !GAZELLE_ENABLE - if (*namelen > saddr.sa.sa_len) { - *namelen = saddr.sa.sa_len; + if (*namelen > IPADDR_SOCKADDR_GET_LEN(&saddr)) { + *namelen = IPADDR_SOCKADDR_GET_LEN(&saddr); } -@@ -3052,7 +3052,7 @@ lwip_sockopt_to_ipopt(int optname) +@@ -3085,7 +3085,7 @@ lwip_sockopt_to_ipopt(int optname) return SOF_KEEPALIVE; case SO_REUSEADDR: return SOF_REUSEADDR; @@ -330,7 +330,7 @@ index 2cb6f22..356e345 100644 case SO_REUSEPORT: return SO_REUSEPORT; #endif -@@ -3928,7 +3928,7 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ +@@ -3961,7 +3961,7 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ return err; } @@ -339,7 +339,7 @@ index 2cb6f22..356e345 100644 int lwip_ioctl(int s, long cmd, ...) { -@@ -3963,7 +3963,7 @@ lwip_ioctl(int s, long cmd, void *argp) +@@ -3996,7 +3996,7 @@ lwip_ioctl(int s, long cmd, void *argp) if (!sock) { return -1; } @@ -348,16 +348,16 @@ index 2cb6f22..356e345 100644 switch (cmd) { #if LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE -@@ -4107,7 +4107,7 @@ lwip_fcntl(int s, int cmd, int val) +@@ -4140,7 +4140,7 @@ lwip_fcntl(int s, int cmd, int val) break; default: LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); -#if USE_LIBOS +#if GAZELLE_ENABLE - sock_set_errno(sock, 0); /* not yet implemented, but we return 0 for compatilbe with app */ + sock_errno(sock, 0); /* not yet implemented, but we return 0 for compatilbe with app */ ret = 0; #else -@@ -4375,7 +4375,7 @@ lwip_socket_drop_registered_mld6_memberships(int s) +@@ -4408,7 +4408,7 @@ lwip_socket_drop_registered_mld6_memberships(int s) } #endif /* LWIP_IPV6_MLD */ @@ -366,7 +366,7 @@ index 2cb6f22..356e345 100644 void lwip_sock_init(void) { if (sockets_num == 0) { -@@ -4400,6 +4400,6 @@ void lwip_exit(void) +@@ -4433,6 +4433,6 @@ void lwip_exit(void) return; } @@ -375,7 +375,7 @@ index 2cb6f22..356e345 100644 #endif /* LWIP_SOCKET */ diff --git a/src/api/tcpip.c b/src/api/tcpip.c -index d3d0b55..fe7a7bd 100644 +index 05adfe0..d0d3cba 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -123,13 +123,13 @@ again: @@ -394,7 +394,7 @@ index d3d0b55..fe7a7bd 100644 { struct tcpip_msg *msg; LWIP_UNUSED_ARG(arg); -@@ -247,7 +247,7 @@ tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn) +@@ -252,7 +252,7 @@ tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn) #if LWIP_TCPIP_CORE_LOCKING_INPUT err_t ret; LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_inpkt: PACKET %p/%p\n", (void *)p, (void *)inp)); @@ -403,7 +403,7 @@ index d3d0b55..fe7a7bd 100644 sys_timer_run(); #endif LOCK_TCPIP_CORE(); -@@ -329,7 +329,7 @@ tcpip_callback(tcpip_callback_fn function, void *ctx) +@@ -334,7 +334,7 @@ tcpip_callback(tcpip_callback_fn function, void *ctx) msg->msg.cb.function = function; msg->msg.cb.ctx = ctx; @@ -412,7 +412,7 @@ index d3d0b55..fe7a7bd 100644 sys_timer_run(); #endif sys_mbox_post(&tcpip_mbox, msg); -@@ -368,7 +368,7 @@ tcpip_try_callback(tcpip_callback_fn function, void *ctx) +@@ -373,7 +373,7 @@ tcpip_try_callback(tcpip_callback_fn function, void *ctx) msg->msg.cb.function = function; msg->msg.cb.ctx = ctx; @@ -421,7 +421,7 @@ index d3d0b55..fe7a7bd 100644 sys_timer_run(); #endif if (sys_mbox_trypost(&tcpip_mbox, msg) != ERR_OK) { -@@ -452,7 +452,7 @@ tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem) +@@ -457,7 +457,7 @@ tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem) { #if LWIP_TCPIP_CORE_LOCKING LWIP_UNUSED_ARG(sem); @@ -430,7 +430,7 @@ index d3d0b55..fe7a7bd 100644 sys_timer_run(); #endif LOCK_TCPIP_CORE(); -@@ -492,7 +492,7 @@ tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call) +@@ -497,7 +497,7 @@ tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call) #if LWIP_TCPIP_CORE_LOCKING err_t err; LOCK_TCPIP_CORE(); @@ -439,7 +439,7 @@ index d3d0b55..fe7a7bd 100644 sys_timer_run(); #endif err = fn(call); -@@ -558,7 +558,7 @@ tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx) +@@ -563,7 +563,7 @@ tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx) msg->msg.cb.function = function; msg->msg.cb.ctx = ctx; @@ -448,7 +448,7 @@ index d3d0b55..fe7a7bd 100644 sys_timer_run(); #endif return (struct tcpip_callback_msg *)msg; -@@ -638,7 +638,7 @@ tcpip_init(tcpip_init_done_fn initfunc, void *arg) +@@ -686,7 +686,7 @@ tcpip_init(tcpip_init_done_fn initfunc, void *arg) } #endif /* LWIP_TCPIP_CORE_LOCKING */ @@ -458,10 +458,10 @@ index d3d0b55..fe7a7bd 100644 #endif } diff --git a/src/core/ipv4/etharp.c b/src/core/ipv4/etharp.c -index f1903e4..5a1a834 100644 +index 2d477bd..6a9117a 100644 --- a/src/core/ipv4/etharp.c +++ b/src/core/ipv4/etharp.c -@@ -482,7 +482,7 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et +@@ -483,7 +483,7 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et struct pbuf *p = arp_table[i].q; arp_table[i].q = NULL; #endif /* ARP_QUEUEING */ @@ -470,7 +470,7 @@ index f1903e4..5a1a834 100644 struct pbuf *tmp = p->next; while (tmp != NULL) { tmp->ref--; -@@ -1034,7 +1034,7 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q) +@@ -1035,7 +1035,7 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q) } else { /* referencing the old pbuf is enough */ p = q; @@ -480,7 +480,7 @@ index f1903e4..5a1a834 100644 while (tmp != NULL) { pbuf_ref(tmp); diff --git a/src/core/ipv4/icmp.c b/src/core/ipv4/icmp.c -index c58ae25..402ba69 100644 +index 0404608..0a3b1c3 100644 --- a/src/core/ipv4/icmp.c +++ b/src/core/ipv4/icmp.c @@ -51,7 +51,7 @@ @@ -493,7 +493,7 @@ index c58ae25..402ba69 100644 #endif diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c -index d823491..1b70bb5 100644 +index 8ef1a55..42f4bd5 100644 --- a/src/core/ipv4/ip4.c +++ b/src/core/ipv4/ip4.c @@ -59,7 +59,7 @@ @@ -505,7 +505,7 @@ index d823491..1b70bb5 100644 #include "dpdk_cksum.h" #endif -@@ -1034,13 +1034,13 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d +@@ -1068,13 +1068,13 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d #endif /* ENABLE_LOOPBACK */ #if IP_FRAG /* don't fragment if interface has mtu set to 0 [loopif] */ @@ -522,7 +522,7 @@ index d823491..1b70bb5 100644 #endif #endif /* IP_FRAG */ diff --git a/src/core/ipv4/ip4_frag.c b/src/core/ipv4/ip4_frag.c -index c60523d..f15b798 100644 +index 727a257..dadf395 100644 --- a/src/core/ipv4/ip4_frag.c +++ b/src/core/ipv4/ip4_frag.c @@ -51,7 +51,7 @@ @@ -565,7 +565,7 @@ index 454ba32..fca1b0c 100644 #ifdef LWIP_HOOK_FILENAME #include LWIP_HOOK_FILENAME diff --git a/src/core/pbuf.c b/src/core/pbuf.c -index ad75aa6..dd71519 100644 +index 9da050a..112baeb 100644 --- a/src/core/pbuf.c +++ b/src/core/pbuf.c @@ -83,7 +83,7 @@ @@ -586,7 +586,7 @@ index ad75aa6..dd71519 100644 /* alloc mbuf avoid send copy */ p = lwip_alloc_pbuf(layer, length, type); #else -@@ -753,7 +753,7 @@ pbuf_free(struct pbuf *p) +@@ -755,7 +755,7 @@ pbuf_free(struct pbuf *p) /* de-allocate all consecutive pbufs from the head of the chain that * obtain a zero reference count after decrementing*/ while (p != NULL) { @@ -595,8 +595,8 @@ index ad75aa6..dd71519 100644 if (p->next) rte_prefetch0(p->next); #endif -@@ -1027,7 +1027,7 @@ pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_ - len_calc = p_to->len - offset_to; +@@ -1024,7 +1024,7 @@ pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_ + len = p_to->len - offset_to; } -#if USE_LIBOS && (CHECKSUM_GEN_IP_HW || CHECKSUM_GEN_TCP_HW) @@ -605,7 +605,7 @@ index ad75aa6..dd71519 100644 p_to->l3_len = p_from->l3_len; p_to->ol_flags = p_from->ol_flags; diff --git a/src/core/tcp.c b/src/core/tcp.c -index 3171c5e..69a39f6 100644 +index 2cc1174..9023dde 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -183,7 +183,7 @@ PER_THREAD struct tcp_pcb *tcp_tw_pcbs; @@ -728,7 +728,7 @@ index 3171c5e..69a39f6 100644 lpcb->connect_num = 0; lpcb->next_same_port_pcb = NULL; -@@ -992,7 +992,7 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) +@@ -995,7 +995,7 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) /* copy over ext_args to listening pcb */ memcpy(&lpcb->ext_args, &pcb->ext_args, sizeof(pcb->ext_args)); #endif @@ -737,7 +737,7 @@ index 3171c5e..69a39f6 100644 /* pcb transfer to lpcb and reg into tcp_listen_pcbs. freeing pcb shouldn't release sock table in here. * local_port=0 avoid to release sock table in tcp_free */ pcb->local_port = 0; -@@ -1006,7 +1006,7 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) +@@ -1009,7 +1009,7 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) tcp_backlog_set(lpcb, backlog); #endif /* TCP_LISTEN_BACKLOG */ @@ -746,7 +746,7 @@ index 3171c5e..69a39f6 100644 if (first_same_port_pcb != NULL) { TCP_REG_SAMEPORT((struct tcp_pcb_listen *)first_same_port_pcb, (struct tcp_pcb_listen *)lpcb); } else -@@ -1109,7 +1109,7 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len) +@@ -1112,7 +1112,7 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len) * * @return a new (free) local TCP port number */ @@ -755,7 +755,7 @@ index 3171c5e..69a39f6 100644 static u16_t tcp_new_port(struct tcp_pcb *pcb) #else -@@ -1128,7 +1128,7 @@ tcp_new_port(void) +@@ -1131,7 +1131,7 @@ tcp_new_port(void) } if (__atomic_load_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], __ATOMIC_ACQUIRE) == 0) { @@ -764,7 +764,7 @@ index 3171c5e..69a39f6 100644 if (port_in_stack_queue(pcb->remote_ip.addr, pcb->local_ip.addr, pcb->remote_port, tcp_port)) { tmp_port = tcp_port; __atomic_store_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE); -@@ -1231,7 +1231,7 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, +@@ -1234,7 +1234,7 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, old_local_port = pcb->local_port; if (pcb->local_port == 0) { @@ -773,7 +773,7 @@ index 3171c5e..69a39f6 100644 pcb->local_port = tcp_new_port(pcb); #else pcb->local_port = tcp_new_port(); -@@ -1289,7 +1289,7 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, +@@ -1292,7 +1292,7 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, /* Send a SYN together with the MSS option. */ ret = tcp_enqueue_flags(pcb, TCP_SYN); if (ret == ERR_OK) { @@ -782,7 +782,7 @@ index 3171c5e..69a39f6 100644 vdev_reg_done(REG_RING_TCP_CONNECT, pcb); #endif -@@ -1298,7 +1298,7 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, +@@ -1301,7 +1301,7 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, if (old_local_port != 0) { TCP_RMV(&tcp_bound_pcbs, pcb); } @@ -791,7 +791,7 @@ index 3171c5e..69a39f6 100644 TCP_REG_ACTIVE_HASH(pcb); #endif TCP_REG_ACTIVE(pcb); -@@ -1516,7 +1516,7 @@ tcp_slowtmr_start: +@@ -1519,7 +1519,7 @@ tcp_slowtmr_start: if (prev != NULL) { LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); prev->next = pcb->next; @@ -800,7 +800,7 @@ index 3171c5e..69a39f6 100644 if (pcb->next) pcb->next->prev = prev; //dont set next NULL, it will be used below -@@ -1526,14 +1526,14 @@ tcp_slowtmr_start: +@@ -1529,14 +1529,14 @@ tcp_slowtmr_start: /* This PCB was the first. */ LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); tcp_active_pcbs = pcb->next; @@ -817,7 +817,7 @@ index 3171c5e..69a39f6 100644 TCP_RMV_ACTIVE_HASH(pcb); #endif -@@ -1546,7 +1546,7 @@ tcp_slowtmr_start: +@@ -1549,7 +1549,7 @@ tcp_slowtmr_start: last_state = pcb->state; pcb2 = pcb; pcb = pcb->next; @@ -826,7 +826,7 @@ index 3171c5e..69a39f6 100644 pcb2->next = NULL; #endif tcp_free(pcb2); -@@ -1600,7 +1600,7 @@ tcp_slowtmr_start: +@@ -1603,7 +1603,7 @@ tcp_slowtmr_start: if (prev != NULL) { LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); prev->next = pcb->next; @@ -835,7 +835,7 @@ index 3171c5e..69a39f6 100644 if (pcb->next) pcb->next->prev = prev; //dont set next NULL, it will be used below -@@ -1610,7 +1610,7 @@ tcp_slowtmr_start: +@@ -1613,7 +1613,7 @@ tcp_slowtmr_start: /* This PCB was the first. */ LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); tcp_tw_pcbs = pcb->next; @@ -844,7 +844,7 @@ index 3171c5e..69a39f6 100644 if (pcb->next) pcb->next->prev = NULL; //dont set next NULL, it will be used below -@@ -1619,7 +1619,7 @@ tcp_slowtmr_start: +@@ -1622,7 +1622,7 @@ tcp_slowtmr_start: } pcb2 = pcb; pcb = pcb->next; @@ -853,7 +853,7 @@ index 3171c5e..69a39f6 100644 pcb2->next = NULL; #endif tcp_free(pcb2); -@@ -1790,7 +1790,7 @@ tcp_seg_free(struct tcp_seg *seg) +@@ -1793,7 +1793,7 @@ tcp_seg_free(struct tcp_seg *seg) seg->p = NULL; #endif /* TCP_DEBUG */ } @@ -862,7 +862,7 @@ index 3171c5e..69a39f6 100644 memp_free(MEMP_TCP_SEG, seg); #endif } -@@ -1828,7 +1828,7 @@ tcp_seg_copy(struct tcp_seg *seg) +@@ -1831,7 +1831,7 @@ tcp_seg_copy(struct tcp_seg *seg) LWIP_ASSERT("tcp_seg_copy: invalid seg", seg != NULL); @@ -871,7 +871,7 @@ index 3171c5e..69a39f6 100644 cseg = (struct tcp_seg *)((uint8_t *)seg->p + sizeof(struct pbuf_custom)); #else cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG); -@@ -2371,7 +2371,7 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) +@@ -2377,7 +2377,7 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) #endif /* TCP_QUEUE_OOSEQ */ } @@ -880,7 +880,7 @@ index 3171c5e..69a39f6 100644 vdev_unreg_done(pcb); release_port(pcb->local_port); #endif -@@ -2383,13 +2383,13 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) +@@ -2389,13 +2389,13 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); } @@ -897,7 +897,7 @@ index 3171c5e..69a39f6 100644 /** * Calculates a new initial sequence number for new connections. diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 9f5c34a..dd83260 100644 +index 77dd235..7126eed 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -58,13 +58,13 @@ @@ -936,8 +936,8 @@ index 9f5c34a..dd83260 100644 (tcp_active_htable->size - 1); @@ -301,7 +301,7 @@ tcp_input(struct pbuf *p, struct netif *inp) pcb->local_port == tcphdr->dest && - ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) && - ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { + ip_addr_eq(&pcb->remote_ip, ip_current_src_addr()) && + ip_addr_eq(&pcb->local_ip, ip_current_dest_addr())) { -#if !TCP_PCB_HASH +#if !GAZELLE_TCP_PCB_HASH /* Move this PCB to the front of the list so that subsequent @@ -963,7 +963,7 @@ index 9f5c34a..dd83260 100644 /* Finally, if we still did not get a match, we check all PCBs that @@ -382,7 +382,7 @@ tcp_input(struct pbuf *p, struct netif *inp) } else if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) { - if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) { + if (ip_addr_eq(&lpcb->local_ip, ip_current_dest_addr())) { /* found an exact match */ -#if REUSE_IPPORT +#if GAZELLE_TCP_REUSE_IPPORT @@ -1022,7 +1022,7 @@ index 9f5c34a..dd83260 100644 tcp_pcb_remove_hash(tcp_active_htable, pcb); #endif tcp_pcb_remove(&tcp_active_pcbs, pcb); -@@ -799,12 +799,12 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) +@@ -802,12 +802,12 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) npcb->netif_idx = pcb->netif_idx; /* Register the new PCB so that we can begin receiving segments for it. */ @@ -1037,7 +1037,7 @@ index 9f5c34a..dd83260 100644 vdev_reg_done(REG_RING_TCP_CONNECT, npcb); #endif -@@ -1102,7 +1102,7 @@ tcp_process(struct tcp_pcb *pcb) +@@ -1105,7 +1105,7 @@ tcp_process(struct tcp_pcb *pcb) if (recv_flags & TF_GOT_FIN) { tcp_ack_now(pcb); pcb->state = CLOSE_WAIT; @@ -1046,7 +1046,7 @@ index 9f5c34a..dd83260 100644 API_EVENT(((struct netconn *)pcb->callback_arg), NETCONN_EVT_ERROR, 0); #endif } -@@ -1120,7 +1120,7 @@ tcp_process(struct tcp_pcb *pcb) +@@ -1123,7 +1123,7 @@ tcp_process(struct tcp_pcb *pcb) if (recv_flags & TF_GOT_FIN) { /* passive close */ tcp_ack_now(pcb); pcb->state = CLOSE_WAIT; @@ -1055,7 +1055,7 @@ index 9f5c34a..dd83260 100644 API_EVENT(((struct netconn *)pcb->callback_arg), NETCONN_EVT_ERROR, 0); #endif } -@@ -1134,7 +1134,7 @@ tcp_process(struct tcp_pcb *pcb) +@@ -1137,7 +1137,7 @@ tcp_process(struct tcp_pcb *pcb) ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); tcp_ack_now(pcb); tcp_pcb_purge(pcb); @@ -1064,7 +1064,7 @@ index 9f5c34a..dd83260 100644 TCP_RMV_ACTIVE_HASH(pcb); #endif TCP_RMV_ACTIVE(pcb); -@@ -1155,7 +1155,7 @@ tcp_process(struct tcp_pcb *pcb) +@@ -1158,7 +1158,7 @@ tcp_process(struct tcp_pcb *pcb) LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); tcp_ack_now(pcb); tcp_pcb_purge(pcb); @@ -1073,7 +1073,7 @@ index 9f5c34a..dd83260 100644 TCP_RMV_ACTIVE_HASH(pcb); #endif TCP_RMV_ACTIVE(pcb); -@@ -1168,7 +1168,7 @@ tcp_process(struct tcp_pcb *pcb) +@@ -1171,7 +1171,7 @@ tcp_process(struct tcp_pcb *pcb) if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) { LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); tcp_pcb_purge(pcb); @@ -1082,16 +1082,7 @@ index 9f5c34a..dd83260 100644 TCP_RMV_ACTIVE_HASH(pcb); #endif TCP_RMV_ACTIVE(pcb); -@@ -1377,7 +1377,7 @@ tcp_receive(struct tcp_pcb *pcb) - if (pcb->lastack == ackno) { - found_dataack = 1; - ++pcb->dataacks; -- if (pcb->dataacks > MAX_DATA_ACK_NUM) { -+ if (pcb->dataacks > GAZELLE_TCP_MAX_DATA_ACK_NUM) { - if (tcp_rexmit(pcb) == ERR_OK) { - pcb->rtime = 0; - pcb->dataacks = 0; -@@ -1775,7 +1775,7 @@ tcp_receive(struct tcp_pcb *pcb) +@@ -1749,7 +1749,7 @@ tcp_receive(struct tcp_pcb *pcb) recv_flags |= TF_GOT_FIN; if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ pcb->state = CLOSE_WAIT; @@ -1101,7 +1092,7 @@ index 9f5c34a..dd83260 100644 #endif } diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c -index bf23381..1b3c5af 100644 +index eafa5a6..240148b 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -80,7 +80,7 @@ @@ -1113,7 +1104,7 @@ index bf23381..1b3c5af 100644 #include "lwipsock.h" #include #if CHECKSUM_GEN_TCP_HW -@@ -162,7 +162,7 @@ tcp_route(const struct tcp_pcb *pcb, const ip_addr_t *src, const ip_addr_t *dst) +@@ -165,7 +165,7 @@ tcp_route(const struct tcp_pcb *pcb, const ip_addr_t *src, const ip_addr_t *dst) * The TCP header is filled in except ackno and wnd. * p is freed on failure. */ @@ -1122,7 +1113,7 @@ index bf23381..1b3c5af 100644 void tcp_init_segment(struct tcp_seg *seg, const struct tcp_pcb *pcb, struct pbuf *p, u8_t hdrflags, u32_t seqno, u8_t optflags) { -@@ -515,7 +515,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -518,7 +518,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) * pos records progress as data is segmented. */ @@ -1131,7 +1122,7 @@ index bf23381..1b3c5af 100644 /* Find the tail of the unsent queue. */ if (pcb->unsent != NULL) { u16_t space; -@@ -631,9 +631,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -634,9 +634,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) pcb->unsent_oversize == 0); #endif /* TCP_OVERSIZE */ } @@ -1143,7 +1134,7 @@ index bf23381..1b3c5af 100644 /* * Phase 3: Create new segments. -@@ -651,7 +651,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -654,7 +654,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) u8_t chksum_swapped = 0; #endif /* TCP_CHECKSUM_ON_COPY */ @@ -1152,7 +1143,7 @@ index bf23381..1b3c5af 100644 if (apiflags & TCP_WRITE_FLAG_COPY) { /* If copy is set, memory should be allocated and data copied * into pbuf */ -@@ -698,13 +698,13 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -701,13 +701,13 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) /* Concatenate the headers and data pbufs together. */ pbuf_cat(p/*header*/, p2/*data*/); } @@ -1168,7 +1159,7 @@ index bf23381..1b3c5af 100644 queuelen += pbuf_clen(p); -@@ -714,7 +714,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -717,7 +717,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) if (queuelen > LWIP_MIN(TCP_SND_QUEUELEN, TCP_SNDQUEUELEN_OVERFLOW)) { LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n", queuelen, (int)TCP_SND_QUEUELEN)); @@ -1177,7 +1168,7 @@ index bf23381..1b3c5af 100644 if (pos > 0) { queuelen -= pbuf_clen(p); break; -@@ -726,7 +726,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -729,7 +729,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) } if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { @@ -1186,7 +1177,7 @@ index bf23381..1b3c5af 100644 if (pos > 0) { queuelen -= pbuf_clen(p); break; -@@ -759,7 +759,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -762,7 +762,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); pos += seglen; @@ -1195,7 +1186,7 @@ index bf23381..1b3c5af 100644 write_lwip_over((struct lwip_sock*)arg); #endif } -@@ -847,7 +847,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -850,7 +850,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) /* * Finally update the pcb state. */ @@ -1204,7 +1195,7 @@ index bf23381..1b3c5af 100644 if (queue) { pcb->last_unsent = prev_seg; } -@@ -876,7 +876,7 @@ memerr: +@@ -879,7 +879,7 @@ memerr: tcp_set_flags(pcb, TF_NAGLEMEMERR); TCP_STATS_INC(tcp.memerr); @@ -1213,7 +1204,7 @@ index bf23381..1b3c5af 100644 if (concat_p != NULL) { pbuf_free(concat_p); } -@@ -1307,7 +1307,7 @@ tcp_build_wnd_scale_option(u32_t *opts) +@@ -1310,7 +1310,7 @@ tcp_build_wnd_scale_option(u32_t *opts) } #endif @@ -1222,7 +1213,7 @@ index bf23381..1b3c5af 100644 static struct tcp_seg *tcp_output_over(struct tcp_pcb *pcb, struct tcp_seg *seg, struct tcp_seg *useg) { if (TCP_TCPLEN(seg) > 0) { -@@ -1472,7 +1472,7 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1475,7 +1475,7 @@ tcp_output(struct tcp_pcb *pcb) /* data available and window allows it to be sent? */ u32_t send_len = 0; @@ -1231,7 +1222,7 @@ index bf23381..1b3c5af 100644 if ((get_eth_params_tx_ol() & DEV_TX_OFFLOAD_TCP_TSO) && pcb->need_tso_send) { while(seg && send_len < 0xffff) { /** -@@ -1485,7 +1485,7 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1488,7 +1488,7 @@ tcp_output(struct tcp_pcb *pcb) struct pbuf *pre_pbuf = NULL; u8_t pbuf_chain_len = 0; u32_t next_seqno = lwip_ntohl(seg->tcphdr->seqno); @@ -1240,7 +1231,7 @@ index bf23381..1b3c5af 100644 u32_t seg_seqno = lwip_ntohl(seg->tcphdr->seqno); if (seg_seqno - pcb->lastack + seg->len > wnd) { if (first_pbuf) -@@ -1501,7 +1501,7 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1504,7 +1504,7 @@ tcp_output(struct tcp_pcb *pcb) goto output_done; } @@ -1249,7 +1240,7 @@ index bf23381..1b3c5af 100644 break; } if (first_pbuf == NULL && (seg->next == NULL || seg->next->len < TCP_MSS)) { -@@ -1771,7 +1771,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif +@@ -1774,7 +1774,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif } #endif @@ -1259,7 +1250,7 @@ index bf23381..1b3c5af 100644 rte_prefetch0((uint8_t *)(seg->p) - sizeof(struct rte_mbuf) - sizeof(uint64_t) * 2); #endif diff --git a/src/core/timeouts.c b/src/core/timeouts.c -index 0542a32..2b80b0a 100644 +index 477369f..610a2d7 100644 --- a/src/core/timeouts.c +++ b/src/core/timeouts.c @@ -442,7 +442,7 @@ sys_timeouts_sleeptime(void) @@ -1335,7 +1326,7 @@ index 7059488..988b017 100644 #endif /* __HLIST_H__ */ diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h -index 430a7a0..197faef 100644 +index d12312c..6bf8b6a 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -141,16 +141,16 @@ enum netconn_type { @@ -1377,10 +1368,10 @@ index 430a7a0..197faef 100644 #endif }; diff --git a/src/include/lwip/ip.h b/src/include/lwip/ip.h -index 7f55fb3..1c6988b 100644 +index ef11160..b6ab031 100644 --- a/src/include/lwip/ip.h +++ b/src/include/lwip/ip.h -@@ -97,7 +97,7 @@ struct ip_pcb { +@@ -108,7 +108,7 @@ struct ip_pcb { /* * Option flags per-socket. These are the same like SO_XXX in sockets.h */ @@ -1389,7 +1380,7 @@ index 7f55fb3..1c6988b 100644 #define SOF_REUSEADDR 0x02U /* allow local address reuse */ #define SOF_KEEPALIVE 0x09U /* keep connections alive */ #define SOF_BROADCAST 0x06U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ -@@ -105,7 +105,7 @@ struct ip_pcb { +@@ -116,7 +116,7 @@ struct ip_pcb { #define SOF_REUSEADDR 0x04U /* allow local address reuse */ #define SOF_KEEPALIVE 0x08U /* keep connections alive */ #define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ @@ -1444,10 +1435,10 @@ index 64d8f31..1763836 100644 /** diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h -index 718816b..0376f60 100644 +index 1d97816..527f2d7 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h -@@ -3525,7 +3525,7 @@ +@@ -3594,7 +3594,7 @@ /** * EPOLL_DEBUG: Enable debugging in epoll.c. */ @@ -1456,7 +1447,7 @@ index 718816b..0376f60 100644 #define EPOLL_DEBUG LWIP_DBG_OFF #endif /** -@@ -3535,7 +3535,7 @@ +@@ -3604,7 +3604,7 @@ /** * ETHDEV_DEBUG: Enable debugging in ethdev.c. */ @@ -1465,7 +1456,7 @@ index 718816b..0376f60 100644 #define ETHDEV_DEBUG LWIP_DBG_OFF #endif /** -@@ -3545,7 +3545,7 @@ +@@ -3614,7 +3614,7 @@ /** * ETHDEV_DEBUG: Enable debugging in ethdev.c. */ @@ -1474,7 +1465,7 @@ index 718816b..0376f60 100644 #define SYSCALL_DEBUG LWIP_DBG_OFF #endif /** -@@ -3555,7 +3555,7 @@ +@@ -3624,7 +3624,7 @@ /** * CONTROL_DEBUG: Enable debugging in control_plane.c. */ @@ -1484,7 +1475,7 @@ index 718816b..0376f60 100644 #endif /** diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h -index 1124408..a2e8e01 100644 +index f817126..168250e 100644 --- a/src/include/lwip/pbuf.h +++ b/src/include/lwip/pbuf.h @@ -220,7 +220,7 @@ struct pbuf { @@ -1535,7 +1526,7 @@ index 395ac0c..66d7e4e 100644 * A list of pools of pbuf's used by LWIP. * diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h -index 97f799e..ddae3fd 100644 +index 02481da..537683f 100644 --- a/src/include/lwip/priv/tcp_priv.h +++ b/src/include/lwip/priv/tcp_priv.h @@ -340,7 +340,7 @@ extern PER_THREAD struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in T @@ -1632,10 +1623,10 @@ index 97f799e..ddae3fd 100644 #define TCP_REG_ACTIVE(npcb) \ do { \ diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h -index 3c5b87b..58acf0f 100644 +index ca5bf6e..8e41155 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h -@@ -57,7 +57,7 @@ extern "C" { +@@ -64,7 +64,7 @@ extern "C" { /* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED to prevent this code from redefining it. */ @@ -1644,7 +1635,7 @@ index 3c5b87b..58acf0f 100644 #define SA_FAMILY_T_DEFINED typedef u16_t sa_family_t; #endif -@@ -74,7 +74,7 @@ typedef u16_t in_port_t; +@@ -81,7 +81,7 @@ typedef u16_t in_port_t; #if LWIP_IPV4 /* members are in network byte order */ struct sockaddr_in { @@ -1653,7 +1644,7 @@ index 3c5b87b..58acf0f 100644 u8_t sin_len; #endif sa_family_t sin_family; -@@ -97,7 +97,7 @@ struct sockaddr_in6 { +@@ -104,7 +104,7 @@ struct sockaddr_in6 { #endif /* LWIP_IPV6 */ struct sockaddr { @@ -1662,7 +1653,7 @@ index 3c5b87b..58acf0f 100644 u8_t sa_len; #endif sa_family_t sa_family; -@@ -198,7 +198,7 @@ struct ifreq { +@@ -207,7 +207,7 @@ struct ifreq { #define SOCK_DGRAM 2 #define SOCK_RAW 3 @@ -1671,7 +1662,7 @@ index 3c5b87b..58acf0f 100644 #include #else /* -@@ -236,7 +236,7 @@ struct ifreq { +@@ -245,7 +245,7 @@ struct ifreq { * Level number for (get/set)sockopt() to apply to socket itself. */ #define SOL_SOCKET 0xfff /* options for socket level */ @@ -1680,7 +1671,7 @@ index 3c5b87b..58acf0f 100644 /* * Structure used for manipulating linger option. -@@ -289,20 +289,20 @@ struct linger { +@@ -298,20 +298,20 @@ struct linger { /* * Options for level IPPROTO_TCP */ @@ -1704,7 +1695,7 @@ index 3c5b87b..58acf0f 100644 #endif /* LWIP_TCP */ #if LWIP_IPV6 -@@ -505,13 +505,13 @@ typedef struct fd_set +@@ -514,13 +514,13 @@ typedef struct fd_set unsigned char fd_bits [(FD_SETSIZE+7)/8]; } fd_set; @@ -1720,7 +1711,7 @@ index 3c5b87b..58acf0f 100644 #if !defined(POLLIN) && !defined(POLLOUT) /* come from bits/poll.h */ #define POLLIN 0x001 -@@ -526,7 +526,7 @@ typedef struct fd_set +@@ -535,7 +535,7 @@ typedef struct fd_set #define POLLWRBAND 0x200 #define POLLHUP 0x010 #endif @@ -1729,7 +1720,7 @@ index 3c5b87b..58acf0f 100644 #if LWIP_SOCKET_POLL /* poll-related defines and types */ -@@ -664,13 +664,13 @@ int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptse +@@ -683,13 +683,13 @@ int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptse int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout); #endif @@ -1745,7 +1736,7 @@ index 3c5b87b..58acf0f 100644 const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size); int lwip_inet_pton(int af, const char *src, void *dst); -@@ -740,7 +740,7 @@ int lwip_inet_pton(int af, const char *src, void *dst); +@@ -759,7 +759,7 @@ int lwip_inet_pton(int af, const char *src, void *dst); /** @ingroup socket */ #define close(s) lwip_close(s) @@ -1754,7 +1745,7 @@ index 3c5b87b..58acf0f 100644 #define fcntl(s,cmd...) lwip_fcntl(s,cmd) #define ioctl(s,cmd...) lwip_ioctl(s,cmd) #else -@@ -748,7 +748,7 @@ int lwip_inet_pton(int af, const char *src, void *dst); +@@ -767,7 +767,7 @@ int lwip_inet_pton(int af, const char *src, void *dst); #define fcntl(s,cmd,val) lwip_fcntl(s,cmd,val) /** @ingroup socket */ #define ioctl(s,cmd,argp) lwip_ioctl(s,cmd,argp) @@ -1764,7 +1755,7 @@ index 3c5b87b..58acf0f 100644 #endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ #endif /* LWIP_COMPAT_SOCKETS != 2 */ diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h -index c2018cb..b822f40 100644 +index 53ebd24..edfdb68 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -51,7 +51,7 @@ @@ -1821,7 +1812,7 @@ index c2018cb..b822f40 100644 struct hlist_node tcp_node; #endif -@@ -421,7 +421,7 @@ struct tcp_pcb { +@@ -420,7 +420,7 @@ struct tcp_pcb { u8_t need_tso_send; }; @@ -1830,7 +1821,7 @@ index c2018cb..b822f40 100644 #define TCP_HTABLE_SIZE MEMP_NUM_NETCONN*12 struct tcp_hashbucket -@@ -471,7 +471,7 @@ static inline unsigned int jhash_3words(unsigned int a, unsigned int b, unsigned +@@ -470,7 +470,7 @@ static inline unsigned int jhash_3words(unsigned int a, unsigned int b, unsigned #define tcppcb_hlist_for_each(tcppcb, node, list) \ hlist_for_each_entry(tcppcb, node, list, tcp_node) @@ -1877,66 +1868,42 @@ index 011ed21..f278ff4 100644 #endif /* __LWIPLOG_H__ */ diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index be58ec3..9cc93bc 100644 +index f8b3294..326edc1 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h -@@ -33,182 +33,204 @@ +@@ -33,180 +33,196 @@ #ifndef __LWIPOPTS_H__ #define __LWIPOPTS_H__ -#define LWIP_TCPIP_CORE_LOCKING 1 -- --#define LWIP_NETCONN_SEM_PER_THREAD 0 -- --#define LWIP_TCP 1 -- --#define LWIP_SO_SENTIMEO 0 -- --#define LIP_SO_LINGER 0 -- --#define MEMP_USE_CUSTOM_POOLS 0 --#define MEM_USE_POOLS 0 -- --#define PER_TCP_PCB_BUFFER (16 * 128) -- --#define MAX_CLIENTS (20000) -- --#define RESERVED_CLIENTS (2000) -- --#define MEMP_NUM_TCP_PCB (MAX_CLIENTS + RESERVED_CLIENTS) -- --/* we use PBUF_POOL instead of PBUF_RAM in tcp_write, so reduce PBUF_RAM size, -- * and do NOT let PBUF_POOL_BUFSIZE less then TCP_MSS +/* + ------------------------------------- + ---------- gazelle options ---------- + ------------------------------------- - */ --#define MEM_SIZE (((PER_TCP_PCB_BUFFER + 128) * MEMP_NUM_TCP_SEG) >> 2) ++*/ +#define LWIP_PERF 1 +#define LWIP_RECORD_PERF 0 --#define MEMP_NUM_TCP_PCB_LISTEN 3000 +-#define LWIP_NETCONN_SEM_PER_THREAD 0 +//#define LWIP_DEBUG 1 +#define GAZELLE_USE_DPDK_LOG 1 --#define MEMP_NUM_TCP_SEG (128 * 128 * 2) +-#define LWIP_TCP 1 +#define GAZELLE_ENABLE 1 +#define PER_THREAD __thread --#define MEMP_NUM_NETCONN (MAX_CLIENTS + RESERVED_CLIENTS) +-#define LWIP_SO_SENTIMEO 0 +#define FRAME_MTU 1500 --#define MEMP_NUM_SYS_SEM (MAX_CLIENTS + RESERVED_CLIENTS) +-#define LIP_SO_LINGER 0 +#define GAZELLE_TCP_PCB_HASH 1 --#define MEMP_NUM_SYS_MBOX (MAX_CLIENTS + RESERVED_CLIENTS) +-#define MEMP_USE_CUSTOM_POOLS 0 +-#define MEM_USE_POOLS 0 +#define GAZELLE_TCP_MAX_DATA_ACK_NUM 256 - --#define PBUF_POOL_SIZE (MAX_CLIENTS * 2) +#define GAZELLE_TCP_MAX_PBUF_CHAIN_LEN 40 --#define MEMP_MEM_MALLOC 0 +-#define PER_TCP_PCB_BUFFER (16 * 128) +/* + ---------------------------------- + ---------- NIC offloads ---------- @@ -1944,7 +1911,7 @@ index be58ec3..9cc93bc 100644 +*/ +#define LWIP_CHECKSUM_CTRL_PER_NETIF 1 /* checksum ability check before checksum*/ --#define LWIP_ARP 1 +-#define MAX_CLIENTS (20000) +// rx cksum +#define CHECKSUM_CHECK_IP 1 /* master switch */ +#define CHECKSUM_CHECK_TCP 1 /* master switch */ @@ -1952,7 +1919,7 @@ index be58ec3..9cc93bc 100644 +#define CHECKSUM_GEN_IP 1 /* master switch */ +#define CHECKSUM_GEN_TCP 1 /* master switch */ --#define ETHARP_SUPPORT_STATIC_ENTRIES 1 +-#define RESERVED_CLIENTS (2000) +// rx offload cksum +#define CHECKSUM_CHECK_IP_HW (1 && CHECKSUM_CHECK_IP) /* hardware switch */ +#define CHECKSUM_CHECK_TCP_HW (1 && CHECKSUM_CHECK_TCP) /* hardware switch */ @@ -1960,46 +1927,44 @@ index be58ec3..9cc93bc 100644 +#define CHECKSUM_GEN_IP_HW (1 && CHECKSUM_GEN_IP) /* hardware switch */ +#define CHECKSUM_GEN_TCP_HW (1 && CHECKSUM_GEN_TCP) /* hardware switch */ --#define LWIP_IPV4 1 +-#define MEMP_NUM_TCP_PCB (MAX_CLIENTS + RESERVED_CLIENTS) +#define CHECKSUM_OFFLOAD_ALL (CHECKSUM_GEN_IP_HW || CHECKSUM_GEN_TCP_HW || CHECKSUM_CHECK_IP_HW || CHECKSUM_CHECK_TCP_HW) --#define IP_FORWARD 0 - --#define IP_REASSEMBLY 1 +-/* we use PBUF_POOL instead of PBUF_RAM in tcp_write, so reduce PBUF_RAM size, +- * and do NOT let PBUF_POOL_BUFSIZE less then TCP_MSS +/* + --------------------------------------- + ---------- lwIP APIs options ---------- + --------------------------------------- -+*/ + */ +-#define MEM_SIZE (((PER_TCP_PCB_BUFFER + 128) * MEMP_NUM_TCP_SEG) >> 2) +#define LWIP_TCPIP_CORE_LOCKING 1 --#define LWIP_UDP 0 +-#define MEMP_NUM_TCP_PCB_LISTEN 3000 +#define LWIP_TCPIP_TIMEOUT 0 --#define LWIP_TCP 1 +-#define MEMP_NUM_TCP_SEG (128 * 128 * 2) +#define TCPIP_MBOX_SIZE (MEMP_NUM_TCPIP_MSG_API) --#define IP_HLEN 20 +-#define MEMP_NUM_NETCONN (MAX_CLIENTS + RESERVED_CLIENTS) +#define LWIP_NETCONN 1 --#define TCP_HLEN 20 +-#define MEMP_NUM_SYS_SEM (MAX_CLIENTS + RESERVED_CLIENTS) +#define LWIP_NETCONN_SEM_PER_THREAD 0 --#define FRAME_MTU 1500 +-#define MEMP_NUM_SYS_MBOX (MAX_CLIENTS + RESERVED_CLIENTS) +#define LWIP_STATS 1 --#define TCP_MSS (FRAME_MTU - IP_HLEN - TCP_HLEN) +-#define PBUF_POOL_SIZE (MAX_CLIENTS * 2) +#define LWIP_STATS_DISPLAY 1 --#define TCP_WND (2500 * TCP_MSS) +-#define MEMP_MEM_MALLOC 0 +#define LWIP_TIMERS 1 --#define TCP_SND_BUF (2500 * TCP_MSS) -+#define LWIP_TIMEVAL_PRIVATE 0 +-#define LWIP_ARP 1 ++#define TCP_SND_BUF (2500 * TCP_MSS) --#define TCP_SND_QUEUELEN (8191) - --#define TCP_SNDLOWAT (TCP_SND_BUF / 5) +-#define ETHARP_SUPPORT_STATIC_ENTRIES 1 +/* + ------------------------------------------------ + ---------- Internal Memory Pool Sizes ---------- @@ -2008,34 +1973,34 @@ index be58ec3..9cc93bc 100644 +#define GAZELLE_MAX_CLIENTS (20000) +#define GAZELLE_RESERVED_CLIENTS (2000) --#define TCP_SNDQUEUELOWAT (TCP_SND_QUEUELEN / 5) +-#define LWIP_IPV4 1 +#define LWIP_SUPPORT_CUSTOM_PBUF 1 --#define TCP_LISTEN_BACKLOG 1 +-#define IP_FORWARD 0 +#define MEMP_MEM_MALLOC 0 +#define MEM_LIBC_MALLOC 0 +#define MEM_USE_POOLS 0 +#define MEMP_USE_CUSTOM_POOLS 0 --#define TCP_DEFAULT_LISTEN_BACKLOG 0xff +-#define IP_REASSEMBLY 1 +#define MEMP_NUM_TCP_PCB_LISTEN 3000 --#define TCP_OVERSIZE 0 +-#define LWIP_UDP 0 +#define MEMP_NUM_TCP_PCB (GAZELLE_MAX_CLIENTS + GAZELLE_RESERVED_CLIENTS) --#define LWIP_NETIF_API 1 +-#define LWIP_TCP 1 +#define MEMP_NUM_NETCONN (GAZELLE_MAX_CLIENTS + GAZELLE_RESERVED_CLIENTS) --#define DEFAULT_TCP_RECVMBOX_SIZE 4096 +-#define IP_HLEN 20 +#define MEMP_NUM_SYS_SEM (GAZELLE_MAX_CLIENTS + GAZELLE_RESERVED_CLIENTS) --#define DEFAULT_ACCEPTMBOX_SIZE 1024 +-#define TCP_HLEN 20 +#define MEMP_NUM_SYS_MBOX (GAZELLE_MAX_CLIENTS + GAZELLE_RESERVED_CLIENTS) --#define LWIP_NETCONN 1 +-#define FRAME_MTU 1500 +#define PBUF_POOL_SIZE (GAZELLE_MAX_CLIENTS * 2) --#define LWIP_TCPIP_TIMEOUT 0 +-#define TCP_MSS (FRAME_MTU - IP_HLEN - TCP_HLEN) +/* we use PBUF_POOL instead of PBUF_RAM in tcp_write, so reduce PBUF_RAM size, + * and do NOT let PBUF_POOL_BUFSIZE less then TCP_MSS +*/ @@ -2043,9 +2008,7 @@ index be58ec3..9cc93bc 100644 +#define PER_TCP_PCB_BUFFER (16 * 128) +#define MEM_SIZE (((PER_TCP_PCB_BUFFER + 128) * MEMP_NUM_TCP_SEG) >> 2) --#define LWIP_SOCKET 1 - --#define LWIP_TCP_KEEPALIVE 1 +-#define TCP_WND (2500 * TCP_MSS) +/* + --------------------------------- + ---------- ARP options ---------- @@ -2053,21 +2016,19 @@ index be58ec3..9cc93bc 100644 +*/ +#define LWIP_ARP 1 --#define LWIP_STATS 1 +-#define TCP_SND_BUF (2500 * TCP_MSS) +#define ARP_TABLE_SIZE 512 --#define LWIP_STATS_DISPLAY 1 +-#define TCP_SND_QUEUELEN (8191) +#define ARP_QUEUEING 1 --#define LWIP_TIMEVAL_PRIVATE 0 +-#define TCP_SNDLOWAT (TCP_SND_BUF / 5) +#define ARP_QUEUE_LEN 32 --#define USE_LIBOS 1 +-#define TCP_SNDQUEUELOWAT (TCP_SND_QUEUELEN / 5) +#define ETHARP_SUPPORT_STATIC_ENTRIES 1 --//#define LWIP_DEBUG 1 - --#define LWIP_PERF 1 +-#define TCP_LISTEN_BACKLOG 1 +/* + --------------------------------- + ---------- IP options ---------- @@ -2075,78 +2036,69 @@ index be58ec3..9cc93bc 100644 +*/ +#define LWIP_IPV4 1 --#define LWIP_RECORD_PERF 0 +-#define TCP_DEFAULT_LISTEN_BACKLOG 0xff +#define IP_FORWARD 0 --#define LWIP_SOCKET_POLL 0 +-#define TCP_OVERSIZE 0 +#define IP_REASSEMBLY 1 --#define USE_LIBOS_ZC_RING 0 +-#define LWIP_NETIF_API 1 +#define IP_HLEN 20 --#define REUSE_IPPORT 1 - --#define MAX_CONN_NUM_PER_THREAD 65535 +-#define DEFAULT_TCP_RECVMBOX_SIZE 4096 +/* + --------------------------------- + ---------- UDP options ---------- + --------------------------------- +*/ +#define LWIP_UDP 0 - --#define SO_REUSE 1 - --#define SIOCSHIWAT 1 ++ +/* + --------------------------------- + ---------- TCP options ---------- + --------------------------------- +*/ +#define LWIP_TCP 1 - --#define O_NONBLOCK 04000 /* same as define in bits/fcntl-linux.h */ ++ +#define TCP_HLEN 20 --#define O_NDELAY O_NONBLOCK -+#define DEFAULT_ACCEPTMBOX_SIZE 1024 + #define DEFAULT_ACCEPTMBOX_SIZE 1024 +#define DEFAULT_TCP_RECVMBOX_SIZE 4096 --#define FIONBIO 0x5421 /* same as define in asm-generic/ioctls.h */ +-#define LWIP_NETCONN 1 +#define TCP_LISTEN_BACKLOG 1 +#define TCP_DEFAULT_LISTEN_BACKLOG 0xff --#define LWIP_SUPPORT_CUSTOM_PBUF 1 +-#define LWIP_TCPIP_TIMEOUT 0 +#define TCP_OVERSIZE 0 +#define LWIP_NETIF_TX_SINGLE_PBUF 0 --#define MEM_LIBC_MALLOC 0 +-#define LWIP_SOCKET 1 +#define TCP_MSS (FRAME_MTU - IP_HLEN - TCP_HLEN) --#define LWIP_TIMERS 1 +-#define LWIP_TCP_KEEPALIVE 1 +#define TCP_WND (2500 * TCP_MSS) --#define TCPIP_MBOX_SIZE (MEMP_NUM_TCPIP_MSG_API) +-#define LWIP_STATS 1 +#define TCP_SND_BUF (2500 * TCP_MSS) --#define TCP_PCB_HASH 1 +-#define LWIP_STATS_DISPLAY 1 +#define TCP_SND_QUEUELEN (8191) --#define USE_DPDK_LOG 1 +-#define LWIP_TIMEVAL_PRIVATE 0 +#define TCP_SNDLOWAT (TCP_SND_BUF / 5) --#define LWIP_EPOOL_WAIT_MAX_EVENTS 30 +-#define USE_LIBOS 1 +#define TCP_SNDQUEUELOWAT (TCP_SND_QUEUELEN / 5) --#define ARP_TABLE_SIZE 512 +-//#define LWIP_DEBUG 1 +#define LWIP_TCP_KEEPALIVE 1 --#define ARP_QUEUEING 1 +-#define LWIP_PERF 1 +#define GAZELLE_TCP_MAX_CONN_PER_THREAD 65535 +#define GAZELLE_TCP_REUSE_IPPORT 1 --#define ARP_QUEUE_LEN 32 - --#define MAX_PBUF_CHAIN_LEN 40 +-#define LWIP_RECORD_PERF 0 +/* + ------------------------------------ + ---------- Socket options ---------- @@ -2154,35 +2106,70 @@ index be58ec3..9cc93bc 100644 +*/ +#define LWIP_SOCKET 1 --#define MIN_TSO_SEG_LEN 256 -+#define LWIP_SOCKET_POLL 0 + #define LWIP_SOCKET_POLL 0 --#define MAX_DATA_ACK_NUM 256 +-#define USE_LIBOS_ZC_RING 0 +- +-#define REUSE_IPPORT 1 +#define LWIP_SO_SNDTIMEO 0 +-#define MAX_CONN_NUM_PER_THREAD 65535 ++#define LWIP_SO_LINGER 0 + + #define SO_REUSE 1 + +-#define SIOCSHIWAT 1 +- +-#define O_NONBLOCK 04000 /* same as define in bits/fcntl-linux.h */ +- +-#define O_NDELAY O_NONBLOCK +- + #define FIONBIO 0x5421 /* same as define in asm-generic/ioctls.h */ + +-#define LWIP_SUPPORT_CUSTOM_PBUF 1 +- +-#define MEM_LIBC_MALLOC 0 +- +-#define LWIP_TIMERS 1 +- +-#define TCPIP_MBOX_SIZE (MEMP_NUM_TCPIP_MSG_API) +- +-#define TCP_PCB_HASH 1 +- +-#define USE_DPDK_LOG 1 +- +-#define LWIP_EPOOL_WAIT_MAX_EVENTS 30 +- +-#define ARP_TABLE_SIZE 512 +- +-#define ARP_QUEUEING 1 +- +-#define ARP_QUEUE_LEN 32 +- +-#define MAX_PBUF_CHAIN_LEN 40 +- +-#define MIN_TSO_SEG_LEN 256 +- -/* --------------------------------------- - * ------- NIC offloads -------- - * --------------------------------------- - */ -#define LWIP_CHECKSUM_CTRL_PER_NETIF 1 /* checksum ability check before checksum*/ -+#define LWIP_SO_LINGER 0 - +- -// rx cksum -#define CHECKSUM_CHECK_IP 1 /* master switch */ -#define CHECKSUM_CHECK_TCP 1 /* master switch */ -// tx cksum -#define CHECKSUM_GEN_IP 1 /* master switch */ -#define CHECKSUM_GEN_TCP 1 /* master switch */ -+#define SO_REUSE 1 - +- -// rx offload cksum -#define CHECKSUM_CHECK_IP_HW (1 && CHECKSUM_CHECK_IP) /* hardware switch */ -#define CHECKSUM_CHECK_TCP_HW (1 && CHECKSUM_CHECK_TCP) /* hardware switch */ -// tx offload cksum -#define CHECKSUM_GEN_IP_HW (1 && CHECKSUM_GEN_IP) /* hardware switch */ -#define CHECKSUM_GEN_TCP_HW (1 && CHECKSUM_GEN_TCP) /* hardware switch */ -+#define FIONBIO 0x5421 /* same as define in asm-generic/ioctls.h */ - +- -#define CHECKSUM_OFFLOAD_ALL (CHECKSUM_GEN_IP_HW || CHECKSUM_GEN_TCP_HW || CHECKSUM_CHECK_IP_HW || CHECKSUM_CHECK_TCP_HW) +#define O_NONBLOCK 04000 /* same as define in bits/fcntl-linux.h */ @@ -2235,7 +2222,7 @@ index a807e3e..f78c9cf 100644 struct lwip_sock *get_socket(int s); struct lwip_sock *get_socket_by_fd(int s); diff --git a/src/netif/ethernet.c b/src/netif/ethernet.c -index ab976a8..fd13f00 100644 +index 0f21ad3..c8bfd19 100644 --- a/src/netif/ethernet.c +++ b/src/netif/ethernet.c @@ -56,7 +56,7 @@ diff --git a/0056-fix-tso-small-packet-drop-in-kernel-server.patch b/0056-fix-tso-small-packet-drop-in-kernel-server.patch index 997c865..e9306cc 100644 --- a/0056-fix-tso-small-packet-drop-in-kernel-server.patch +++ b/0056-fix-tso-small-packet-drop-in-kernel-server.patch @@ -9,10 +9,10 @@ Subject: [PATCH] fix tso small packet drop in kernel server 2 files changed, 130 insertions(+), 126 deletions(-) diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c -index 8a0d653..b1c317d 100644 +index 240148b..17e495d 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c -@@ -1312,60 +1312,33 @@ tcp_build_wnd_scale_option(u32_t *opts) +@@ -1311,60 +1311,33 @@ tcp_build_wnd_scale_option(u32_t *opts) #endif #if GAZELLE_ENABLE @@ -100,7 +100,7 @@ index 8a0d653..b1c317d 100644 #endif /** * @ingroup tcp_raw -@@ -1471,97 +1444,127 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1470,97 +1443,127 @@ tcp_output(struct tcp_pcb *pcb) pcb->persist_backoff = 0; /* useg should point to last segment on unacked queue */ @@ -299,7 +299,7 @@ index 8a0d653..b1c317d 100644 lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { LWIP_ASSERT("RST not expected here!", (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0); -@@ -1576,7 +1579,6 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1575,7 +1578,6 @@ tcp_output(struct tcp_pcb *pcb) ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)) { break; } @@ -308,11 +308,11 @@ index 8a0d653..b1c317d 100644 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n", pcb->snd_wnd, pcb->cwnd, wnd, diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index 742b4a9..0d2a6d9 100644 +index 326edc1..9f8c923 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h -@@ -55,6 +55,8 @@ - +@@ -54,6 +54,8 @@ + #define GAZELLE_TCP_MAX_DATA_ACK_NUM 256 #define GAZELLE_TCP_MAX_PBUF_CHAIN_LEN 40 +#define GAZELLE_TCP_MIN_TSO_SEG_LEN 256 diff --git a/0057-same-node-gazellectl-a.patch b/0057-same-node-gazellectl-a.patch index 0061f5d..f866de4 100644 --- a/0057-same-node-gazellectl-a.patch +++ b/0057-same-node-gazellectl-a.patch @@ -18,10 +18,10 @@ Subject: [PATCH] same node & gazellectl -a 11 files changed, 148 insertions(+), 3 deletions(-) diff --git a/src/api/sockets.c b/src/api/sockets.c -index 356e345..7a5da26 100644 +index 8ef89ab..7b5606f 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -605,6 +605,10 @@ alloc_socket(struct netconn *newconn, int accepted, int flags) +@@ -645,6 +645,10 @@ alloc_socket(struct netconn *newconn, int accepted, int flags) * (unless it has been created by accept()). */ sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1); sockets[i].errevent = 0; @@ -32,7 +32,7 @@ index 356e345..7a5da26 100644 return i + LWIP_SOCKET_OFFSET; } else { lwip_close(i); -@@ -716,6 +720,11 @@ free_socket(struct lwip_sock *sock, int is_tcp) +@@ -756,6 +760,11 @@ free_socket(struct lwip_sock *sock, int is_tcp) /* Protect socket array */ SYS_ARCH_PROTECT(lev); @@ -44,7 +44,7 @@ index 356e345..7a5da26 100644 freed = free_socket_locked(sock, is_tcp, &conn, &lastdata); SYS_ARCH_UNPROTECT(lev); /* don't use 'sock' after this line, as another task might have allocated it */ -@@ -780,6 +789,18 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) +@@ -819,6 +828,18 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) LWIP_ASSERT("invalid socket index", (newsock >= LWIP_SOCKET_OFFSET) && (newsock < NUM_SOCKETS + LWIP_SOCKET_OFFSET)); #endif /* GAZELLE_ENABLE */ nsock = &sockets[newsock - LWIP_SOCKET_OFFSET]; @@ -64,7 +64,7 @@ index 356e345..7a5da26 100644 /* See event_callback: If data comes in right away after an accept, even * though the server task might not have created a new socket yet. diff --git a/src/core/ipv4/ip4_frag.c b/src/core/ipv4/ip4_frag.c -index f15b798..e01ea51 100644 +index dadf395..b2462d2 100644 --- a/src/core/ipv4/ip4_frag.c +++ b/src/core/ipv4/ip4_frag.c @@ -729,6 +729,7 @@ ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref *p) @@ -94,10 +94,10 @@ index f15b798..e01ea51 100644 /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain * so that it is removed when pbuf_dechain is later called on rambuf. diff --git a/src/core/netif.c b/src/core/netif.c -index 70392cb..86b74a0 100644 +index ded3561..db3c718 100644 --- a/src/core/netif.c +++ b/src/core/netif.c -@@ -1065,7 +1065,7 @@ netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callb +@@ -1101,7 +1101,7 @@ netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callb } #endif /* LWIP_NETIF_LINK_CALLBACK */ @@ -106,7 +106,7 @@ index 70392cb..86b74a0 100644 /** * @ingroup netif * Send an IP packet to be received on the same netif (loopif-like). -@@ -1184,6 +1184,7 @@ netif_loop_output(struct netif *netif, struct pbuf *p) +@@ -1220,6 +1220,7 @@ netif_loop_output(struct netif *netif, struct pbuf *p) return ERR_OK; } @@ -114,7 +114,7 @@ index 70392cb..86b74a0 100644 #if LWIP_HAVE_LOOPIF #if LWIP_IPV4 -@@ -1205,7 +1206,7 @@ netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ad +@@ -1241,7 +1242,7 @@ netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ad #endif /* LWIP_IPV6 */ #endif /* LWIP_HAVE_LOOPIF */ @@ -123,7 +123,7 @@ index 70392cb..86b74a0 100644 /** * Call netif_poll() in the main loop of your application. This is to prevent * reentering non-reentrant functions like tcp_input(). Packets passed to -@@ -1277,6 +1278,7 @@ netif_poll(struct netif *netif) +@@ -1313,6 +1314,7 @@ netif_poll(struct netif *netif) } SYS_ARCH_UNPROTECT(lev); } @@ -131,7 +131,7 @@ index 70392cb..86b74a0 100644 #if !LWIP_NETIF_LOOPBACK_MULTITHREADING /** -@@ -1292,7 +1294,6 @@ netif_poll_all(void) +@@ -1328,7 +1330,6 @@ netif_poll_all(void) } } #endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ @@ -140,7 +140,7 @@ index 70392cb..86b74a0 100644 #if LWIP_NUM_NETIF_CLIENT_DATA > 0 /** diff --git a/src/core/pbuf.c b/src/core/pbuf.c -index dd71519..2385e57 100644 +index 112baeb..ab1edff 100644 --- a/src/core/pbuf.c +++ b/src/core/pbuf.c @@ -69,6 +69,7 @@ @@ -159,7 +159,7 @@ index dd71519..2385e57 100644 } /** -@@ -777,9 +779,13 @@ pbuf_free(struct pbuf *p) +@@ -779,9 +781,13 @@ pbuf_free(struct pbuf *p) #if LWIP_SUPPORT_CUSTOM_PBUF /* is this a custom pbuf? */ if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) { @@ -174,7 +174,7 @@ index dd71519..2385e57 100644 #endif /* LWIP_SUPPORT_CUSTOM_PBUF */ { diff --git a/src/core/tcp.c b/src/core/tcp.c -index 69a39f6..538a664 100644 +index 9023dde..34e99df 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -116,6 +116,8 @@ @@ -205,7 +205,7 @@ index 69a39f6..538a664 100644 vdev_unreg_done(pcb); release_port(pcb->local_port); #endif -@@ -996,6 +1010,15 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) +@@ -999,6 +1013,15 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) /* pcb transfer to lpcb and reg into tcp_listen_pcbs. freeing pcb shouldn't release sock table in here. * local_port=0 avoid to release sock table in tcp_free */ pcb->local_port = 0; @@ -221,7 +221,7 @@ index 69a39f6..538a664 100644 #endif tcp_free(pcb); #if LWIP_CALLBACK_API -@@ -1262,6 +1285,16 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, +@@ -1265,6 +1288,16 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, #endif /* SO_REUSE */ } @@ -238,7 +238,7 @@ index 69a39f6..538a664 100644 iss = tcp_next_iss(pcb); pcb->rcv_nxt = 0; pcb->snd_nxt = iss; -@@ -2090,7 +2123,13 @@ tcp_alloc(u8_t prio) +@@ -2095,6 +2128,11 @@ tcp_alloc(u8_t prio) pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; #endif /* LWIP_TCP_KEEPALIVE */ @@ -247,13 +247,11 @@ index 69a39f6..538a664 100644 + pcb->client_tx_ring = NULL; + pcb->free_ring = 0; +#endif + pcb_tci_init(pcb); } -+ return pcb; - } - diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index dd83260..719cf04 100644 +index 7126eed..a952903 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -42,6 +42,7 @@ @@ -264,7 +262,7 @@ index dd83260..719cf04 100644 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ -@@ -806,6 +807,11 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) +@@ -809,6 +810,11 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) #if GAZELLE_ENABLE vdev_reg_done(REG_RING_TCP_CONNECT, npcb); @@ -277,10 +275,10 @@ index dd83260..719cf04 100644 /* Parse any options in the SYN. */ diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c -index 8100e18..b1c317d 100644 +index 17e495d..7aad1b8 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c -@@ -725,6 +725,10 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -728,6 +728,10 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) goto memerr; } @@ -291,7 +289,7 @@ index 8100e18..b1c317d 100644 if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { #if GAZELLE_ENABLE if (pos > 0) { -@@ -1705,6 +1709,10 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif +@@ -1708,6 +1712,10 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif int seg_chksum_was_swapped = 0; #endif @@ -302,7 +300,7 @@ index 8100e18..b1c317d 100644 LWIP_ASSERT("tcp_output_segment: invalid seg", seg != NULL); LWIP_ASSERT("tcp_output_segment: invalid pcb", pcb != NULL); LWIP_ASSERT("tcp_output_segment: invalid netif", netif != NULL); -@@ -1899,6 +1907,8 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif +@@ -1902,6 +1910,8 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif PERF_START(PERF_LAYER_IP, PERF_POINT_IP_SEND); NETIF_SET_HINTS(netif, &(pcb->netif_hints)); @@ -311,8 +309,8 @@ index 8100e18..b1c317d 100644 err = ip_output_if(seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_TCP, netif); NETIF_RESET_HINTS(netif); -@@ -2236,6 +2246,7 @@ tcp_output_control_segment(struct tcp_pcb *pcb, struct pbuf *p, - err_t err; +@@ -2238,6 +2248,7 @@ tcp_output_control_segment(struct tcp_pcb *pcb, struct pbuf *p, + { struct netif *netif; + p->pcb = pcb; @@ -320,7 +318,7 @@ index 8100e18..b1c317d 100644 if (pcb == NULL || pcb->pcb_if == NULL) { diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h -index 6c4ca44..9321afc 100644 +index ae8e5e7..46ff26a 100644 --- a/src/include/lwip/pbuf.h +++ b/src/include/lwip/pbuf.h @@ -235,6 +235,7 @@ struct pbuf { @@ -342,7 +340,7 @@ index 6c4ca44..9321afc 100644 #endif /* LWIP_SUPPORT_CUSTOM_PBUF */ diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h -index b822f40..e13099c 100644 +index edfdb68..f968441 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -260,6 +260,9 @@ struct tcp_pcb_listen { @@ -355,7 +353,7 @@ index b822f40..e13099c 100644 }; -@@ -418,6 +421,13 @@ struct tcp_pcb { +@@ -417,6 +420,13 @@ struct tcp_pcb { u8_t rcv_scale; #endif @@ -370,10 +368,10 @@ index b822f40..e13099c 100644 }; diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index 414ead4..0d2a6d9 100644 +index 9f8c923..5b6bf6e 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h -@@ -235,4 +235,11 @@ +@@ -227,4 +227,11 @@ #define SIOCSHIWAT 1 diff --git a/0059-fix-last_unsent-last_unacked.patch b/0059-fix-last_unsent-last_unacked.patch index e51d645..31b9424 100644 --- a/0059-fix-last_unsent-last_unacked.patch +++ b/0059-fix-last_unsent-last_unacked.patch @@ -8,47 +8,11 @@ Subject: [PATCH] fix last_unsent/last_unacked src/core/tcp_out.c | 18 +++++++++++++----- 2 files changed, 26 insertions(+), 17 deletions(-) -diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 719cf04..7e7d70a 100644 ---- a/src/core/tcp_in.c -+++ b/src/core/tcp_in.c -@@ -1375,18 +1375,19 @@ tcp_receive(struct tcp_pcb *pcb) - } - } - } -- } -- /* fast rexmit when receive too many acks with data */ -- if (TCP_SEQ_LT(ackno + 1, pcb->snd_nxt)) { -- if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) { -- if (pcb->rtime >= 0) { -- if (pcb->lastack == ackno) { -- found_dataack = 1; -- ++pcb->dataacks; -- if (pcb->dataacks > GAZELLE_TCP_MAX_DATA_ACK_NUM) { -- if (tcp_rexmit(pcb) == ERR_OK) { -- pcb->rtime = 0; -- pcb->dataacks = 0; -+ } else { -+ /* fast rexmit when receive too many acks with data */ -+ if (TCP_SEQ_LT(ackno + 1, pcb->snd_nxt)) { -+ if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) { -+ if (pcb->rtime >= 0) { -+ if (pcb->lastack == ackno) { -+ found_dataack = 1; -+ ++pcb->dataacks; -+ if ((pcb->dataacks > GAZELLE_TCP_MAX_DATA_ACK_NUM) && (pcb->nrtx < (TCP_MAXRTX / 2))) { -+ if (tcp_rexmit(pcb) == ERR_OK) { -+ pcb->rtime = 0; -+ pcb->dataacks = 0; -+ } - } - } - } diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c -index b1c317d..6250e6b 100644 +index 7aad1b8..f6ec4f8 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c -@@ -1444,10 +1444,7 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1447,10 +1447,7 @@ tcp_output(struct tcp_pcb *pcb) pcb->persist_backoff = 0; /* useg should point to last segment on unacked queue */ @@ -60,7 +24,7 @@ index b1c317d..6250e6b 100644 /* data available and window allows it to be sent? */ #if GAZELLE_ENABLE -@@ -1515,7 +1512,11 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1518,7 +1515,11 @@ tcp_output(struct tcp_pcb *pcb) return err; } @@ -72,7 +36,7 @@ index b1c317d..6250e6b 100644 if (pcb->state != SYN_SENT) { tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); } -@@ -1535,6 +1536,7 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1538,6 +1539,7 @@ tcp_output(struct tcp_pcb *pcb) if (TCP_TCPLEN(tmp_seg) > 0) { tmp_seg->next = NULL; if (pcb->unacked == NULL) { @@ -80,7 +44,7 @@ index b1c317d..6250e6b 100644 pcb->unacked = tmp_seg; useg = tmp_seg; } else { -@@ -1550,6 +1552,9 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1553,6 +1555,9 @@ tcp_output(struct tcp_pcb *pcb) } else { /* add segment to tail of unacked list */ useg->next = tmp_seg; @@ -90,7 +54,7 @@ index b1c317d..6250e6b 100644 useg = useg->next; } } -@@ -1603,6 +1608,9 @@ end_loop: +@@ -1606,6 +1611,9 @@ end_loop: #if TCP_OVERSIZE_DBGCHECK seg->oversize_left = 0; #endif /* TCP_OVERSIZE_DBGCHECK */ @@ -100,7 +64,7 @@ index b1c317d..6250e6b 100644 pcb->unsent = seg->next; if (pcb->state != SYN_SENT) { tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); -@@ -1709,7 +1717,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif +@@ -1712,7 +1720,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif int seg_chksum_was_swapped = 0; #endif diff --git a/0060-lwip-add-udp-multicast.patch b/0060-lwip-add-udp-multicast.patch index 94e4e30..5a47f33 100644 --- a/0060-lwip-add-udp-multicast.patch +++ b/0060-lwip-add-udp-multicast.patch @@ -16,10 +16,10 @@ Subject: [PATCH] add udp multicast in support 9 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/api/api_msg.c b/src/api/api_msg.c -index 1840c9d..0287c06 100644 +index 5a2e689..98537b8 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c -@@ -282,8 +282,13 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, +@@ -285,8 +285,13 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, #if LWIP_SO_RCVBUF SYS_ARCH_INC(conn->recv_avail, len); #endif /* LWIP_SO_RCVBUF */ @@ -34,7 +34,7 @@ index 1840c9d..0287c06 100644 } #endif /* LWIP_UDP */ diff --git a/src/api/sockets.c b/src/api/sockets.c -index 7a5da26..a0f9d50 100644 +index 7b5606f..bedb86b 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -54,6 +54,7 @@ @@ -45,7 +45,7 @@ index 7a5da26..a0f9d50 100644 #if LWIP_CHECKSUM_ON_COPY #include "lwip/inet_chksum.h" #endif -@@ -1187,7 +1188,7 @@ lwip_recv_tcp_done: +@@ -1222,7 +1223,7 @@ lwip_recv_tcp_done: #endif /* Convert a netbuf's address data to struct sockaddr */ @@ -54,7 +54,7 @@ index 7a5da26..a0f9d50 100644 lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port, struct sockaddr *from, socklen_t *fromlen) { -@@ -1274,6 +1275,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 +@@ -1307,6 +1308,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 apiflags = 0; } @@ -62,7 +62,7 @@ index 7a5da26..a0f9d50 100644 LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw[UDP/RAW]: top sock->lastdata=%p\n", (void *)sock->lastdata.netbuf)); /* Check if there is data left from the last recv operation. */ buf = sock->lastdata.netbuf; -@@ -1361,6 +1363,18 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 +@@ -1394,6 +1396,18 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 sock->lastdata.netbuf = NULL; netbuf_delete(buf); } @@ -81,7 +81,7 @@ index 7a5da26..a0f9d50 100644 if (datagram_len) { *datagram_len = buflen; } -@@ -1409,6 +1423,7 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, +@@ -1451,6 +1465,7 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, done_socket(sock); return -1; } @@ -89,7 +89,7 @@ index 7a5da26..a0f9d50 100644 ret = (ssize_t)LWIP_MIN(LWIP_MIN(len, datagram_len), SSIZE_MAX); if (fromlen) { *fromlen = msg.msg_namelen; -@@ -3956,6 +3971,10 @@ lwip_ioctl(int s, long cmd, ...) +@@ -3998,6 +4013,10 @@ lwip_ioctl(int s, long cmd, ...) struct lwip_sock *sock = posix_api->get_socket(s); u8_t val; @@ -113,7 +113,7 @@ index ebc01a5..57a9670 100644 $(eval $(call register_dir, core, $(SRC))) diff --git a/src/core/udp.c b/src/core/udp.c -index a5f76b9..1398537 100644 +index 24fc174..8a01c76 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -65,6 +65,12 @@ @@ -207,7 +207,7 @@ index df2e2a5..e41644b 100644 const ip_addr_t *src, const ip_addr_t *dst) { diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h -index 0376f60..38c6e9b 100644 +index 527f2d7..e61b3f1 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -133,6 +133,7 @@ @@ -218,7 +218,7 @@ index 0376f60..38c6e9b 100644 #if !defined MEMCPY || defined __DOXYGEN__ #define MEMCPY(dst,src,len) memcpy(dst,src,len) #endif -@@ -1083,7 +1084,7 @@ +@@ -1123,7 +1124,7 @@ * LWIP_IGMP==1: Turn on IGMP module. */ #if !defined LWIP_IGMP || defined __DOXYGEN__ @@ -227,7 +227,7 @@ index 0376f60..38c6e9b 100644 #endif #if !LWIP_IPV4 #undef LWIP_IGMP -@@ -2030,7 +2031,7 @@ +@@ -2092,7 +2093,7 @@ * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. */ #if !defined LWIP_SO_RCVBUF || defined __DOXYGEN__ @@ -237,7 +237,7 @@ index 0376f60..38c6e9b 100644 /** diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h -index 9321afc..fb21134 100644 +index 46ff26a..e08d4fa 100644 --- a/src/include/lwip/pbuf.h +++ b/src/include/lwip/pbuf.h @@ -40,6 +40,8 @@ @@ -259,10 +259,10 @@ index 9321afc..fb21134 100644 /** In case the user needs to store data custom data on a pbuf */ diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h -index 58acf0f..36a47eb 100644 +index 8e41155..a7cec29 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h -@@ -48,6 +48,7 @@ +@@ -52,6 +52,7 @@ #include "lwip/err.h" #include "lwip/inet.h" #include "lwip/errno.h" @@ -270,7 +270,7 @@ index 58acf0f..36a47eb 100644 #include -@@ -323,20 +324,31 @@ struct linger { +@@ -332,20 +333,31 @@ struct linger { #if LWIP_MULTICAST_TX_OPTIONS @@ -302,7 +302,7 @@ index 58acf0f..36a47eb 100644 typedef struct ip_mreq { struct in_addr imr_multiaddr; /* IP multicast address of group */ -@@ -656,6 +668,7 @@ ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags, +@@ -675,6 +687,7 @@ ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags, int lwip_socket(int domain, int type, int protocol); ssize_t lwip_write(int s, const void *dataptr, size_t size); ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt); @@ -310,7 +310,7 @@ index 58acf0f..36a47eb 100644 #if LWIP_SOCKET_SELECT int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout); -@@ -667,6 +680,8 @@ int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout); +@@ -686,6 +699,8 @@ int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout); #if GAZELLE_ENABLE int lwip_ioctl(int s, long cmd, ...); int lwip_fcntl(int s, int cmd, int val); @@ -320,18 +320,18 @@ index 58acf0f..36a47eb 100644 int lwip_ioctl(int s, long cmd, void *argp); int lwip_fcntl(int s, int cmd, int val); diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index 0d2a6d9..bcb0879 100644 +index 5b6bf6e..abc3f15 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h -@@ -175,7 +175,7 @@ +@@ -169,7 +169,7 @@ ---------- UDP options ---------- --------------------------------- */ -#define LWIP_UDP 0 +#define LWIP_UDP 1 - /* + --------------------------------- -- 2.33.0 diff --git a/0061-fix-pbuf-leak-in-udp-connection.patch b/0061-fix-pbuf-leak-in-udp-connection.patch index a75e3fd..3aa8788 100644 --- a/0061-fix-pbuf-leak-in-udp-connection.patch +++ b/0061-fix-pbuf-leak-in-udp-connection.patch @@ -8,7 +8,7 @@ Subject: [PATCH] fix pbuf leak in udp connection 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/udp.c b/src/core/udp.c -index 1398537..9c3cdaa 100644 +index 8a01c76..6261c86 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -933,8 +933,11 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d diff --git a/0062-drop-netbuf-in-recv_udp-to-fix-mem-overflow.patch b/0062-drop-netbuf-in-recv_udp-to-fix-mem-overflow.patch index 7022817..ce9c19e 100644 --- a/0062-drop-netbuf-in-recv_udp-to-fix-mem-overflow.patch +++ b/0062-drop-netbuf-in-recv_udp-to-fix-mem-overflow.patch @@ -15,7 +15,7 @@ Subject: [PATCH] drop-netbuf-in-recv_udp-to-fix-mem-overflow 8 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/api/api_lib.c b/src/api/api_lib.c -index ffa14d6..afdfc11 100644 +index 4cdb965..b22b987 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -655,7 +655,11 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags) @@ -48,10 +48,18 @@ index ffa14d6..afdfc11 100644 * Receive data (in form of a netbuf) from a UDP or RAW netconn * diff --git a/src/api/api_msg.c b/src/api/api_msg.c -index 30929be..b82ebf2 100644 +index 98537b8..35207cc 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c -@@ -253,6 +253,14 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, +@@ -227,7 +227,6 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, + struct netbuf *buf; + struct netconn *conn; + u16_t len; +- err_t err; + #if LWIP_SO_RCVBUF + int recv_avail; + #endif /* LWIP_SO_RCVBUF */ +@@ -255,6 +254,15 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, return; } @@ -63,12 +71,13 @@ index 30929be..b82ebf2 100644 + if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) { + return; +#else /* GAZELLE_UDP_ENABLE */ ++ err_t err; buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); if (buf == NULL) { pbuf_free(p); -@@ -277,17 +285,18 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, - if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { +@@ -281,17 +289,18 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, netbuf_delete(buf); + LWIP_DEBUGF(API_MSG_DEBUG, ("recv_udp: sys_mbox_trypost failed, err=%d\n", err)); return; +#endif /* GAZELLE_UDP_ENABLE */ } else { @@ -89,10 +98,10 @@ index 30929be..b82ebf2 100644 } #endif /* LWIP_UDP */ diff --git a/src/api/sockets.c b/src/api/sockets.c -index dee9230..17691f7 100644 +index bedb86b..a731453 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -1179,7 +1179,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 +@@ -1308,7 +1308,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 apiflags = 0; } @@ -101,7 +110,7 @@ index dee9230..17691f7 100644 LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw[UDP/RAW]: top sock->lastdata=%p\n", (void *)sock->lastdata.netbuf)); /* Check if there is data left from the last recv operation. */ buf = sock->lastdata.netbuf; -@@ -1267,7 +1267,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 +@@ -1396,7 +1396,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 sock->lastdata.netbuf = NULL; netbuf_delete(buf); } @@ -110,7 +119,7 @@ index dee9230..17691f7 100644 LWIP_UNUSED_ARG(copylen); LWIP_UNUSED_ARG(buf); LWIP_UNUSED_ARG(err); -@@ -1278,7 +1278,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 +@@ -1407,7 +1407,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 return ERR_BUF; } @@ -120,10 +129,10 @@ index dee9230..17691f7 100644 *datagram_len = buflen; } diff --git a/src/core/udp.c b/src/core/udp.c -index 170c911..1eb459d 100644 +index 6261c86..5514295 100644 --- a/src/core/udp.c +++ b/src/core/udp.c -@@ -599,6 +599,7 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, +@@ -614,6 +614,7 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, UDP_STATS_INC(udp.rterr); return ERR_RTE; } @@ -131,7 +140,7 @@ index 170c911..1eb459d 100644 uint8_t apiflags = 0; struct pbuf *udp_pbuf = write_lwip_data((struct lwip_sock *)(p->payload), p->tot_len, &apiflags); -@@ -611,14 +612,21 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, +@@ -626,14 +627,21 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, } if (p->port) { @@ -154,10 +163,10 @@ index 170c911..1eb459d 100644 /** diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h -index d3c4f02..6090cab 100644 +index 6bf8b6a..6e6e52d 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h -@@ -338,6 +338,9 @@ err_t netconn_accept(struct netconn *conn, struct netconn **new_conn); +@@ -373,6 +373,9 @@ err_t netconn_accept(struct netconn *conn, struct netconn **new_conn); err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf); err_t netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf); err_t netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags); @@ -168,7 +177,7 @@ index d3c4f02..6090cab 100644 err_t netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags); err_t netconn_tcp_recvd(struct netconn *conn, size_t len); diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h -index 728c5e4..4747f39 100644 +index e08d4fa..9ce3500 100644 --- a/src/include/lwip/pbuf.h +++ b/src/include/lwip/pbuf.h @@ -40,8 +40,10 @@ @@ -194,10 +203,10 @@ index 728c5e4..4747f39 100644 /** In case the user needs to store data custom data on a pbuf */ diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h -index 643093a..2b6e6be 100644 +index a7cec29..a50c691 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h -@@ -330,7 +330,7 @@ struct linger { +@@ -333,7 +333,7 @@ struct linger { #if LWIP_MULTICAST_TX_OPTIONS @@ -206,7 +215,7 @@ index 643093a..2b6e6be 100644 #define IP_MULTICAST_IF 32 #define IP_MULTICAST_TTL 33 #define IP_MULTICAST_LOOP 34 -@@ -341,11 +341,11 @@ struct linger { +@@ -344,11 +344,11 @@ struct linger { #define IP_MULTICAST_TTL 5 #define IP_MULTICAST_IF 6 #define IP_MULTICAST_LOOP 7 @@ -220,7 +229,7 @@ index 643093a..2b6e6be 100644 #define IP_ADD_MEMBERSHIP 35 #define IP_DROP_MEMBERSHIP 36 #else -@@ -354,7 +354,7 @@ struct linger { +@@ -357,7 +357,7 @@ struct linger { */ #define IP_ADD_MEMBERSHIP 3 #define IP_DROP_MEMBERSHIP 4 @@ -230,10 +239,10 @@ index 643093a..2b6e6be 100644 typedef struct ip_mreq { struct in_addr imr_multiaddr; /* IP multicast address of group */ diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index 6b5a2d1..9804aed 100644 +index abc3f15..50220e8 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h -@@ -63,6 +63,10 @@ +@@ -56,6 +56,10 @@ #define GAZELLE_TCP_MIN_TSO_SEG_LEN 256 diff --git a/0063-optimize-avoid-too-many-empty-acks-in-tcp_input.patch b/0063-optimize-avoid-too-many-empty-acks-in-tcp_input.patch index 0fa456e..9e3111b 100644 --- a/0063-optimize-avoid-too-many-empty-acks-in-tcp_input.patch +++ b/0063-optimize-avoid-too-many-empty-acks-in-tcp_input.patch @@ -9,10 +9,10 @@ Signed-off-by: Lemmy Huang 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 7e7d70ab..0abee303 100644 +index a952903..59e854c 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c -@@ -1807,11 +1807,7 @@ tcp_receive(struct tcp_pcb *pcb) +@@ -1780,11 +1780,7 @@ tcp_receive(struct tcp_pcb *pcb) /* Acknowledge the segment(s). */ diff --git a/0065-fix-udp-recvmbox-size-not-set.patch b/0065-fix-udp-recvmbox-size-not-set.patch index e8e5663..238a670 100644 --- a/0065-fix-udp-recvmbox-size-not-set.patch +++ b/0065-fix-udp-recvmbox-size-not-set.patch @@ -8,17 +8,17 @@ Subject: [PATCH] fix udp recvmbox size not set 1 file changed, 1 insertion(+) diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index 6b5c769..f0df0e3 100644 +index 50220e8..1c27051 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h -@@ -180,6 +180,7 @@ +@@ -174,6 +174,7 @@ --------------------------------- */ #define LWIP_UDP 1 +#define DEFAULT_UDP_RECVMBOX_SIZE 4096 - /* + --------------------------------- -- 2.23.0 diff --git a/0067-fix-null-pointer-when-all-zero-address-listen.patch b/0067-fix-null-pointer-when-all-zero-address-listen.patch index aa58a8f..780ccb7 100644 --- a/0067-fix-null-pointer-when-all-zero-address-listen.patch +++ b/0067-fix-null-pointer-when-all-zero-address-listen.patch @@ -8,7 +8,7 @@ Subject: [PATCH] fix null pointer when all zero address listen 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 0abee30..c20c9b5 100644 +index 59e854c..d151a96 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -114,6 +114,36 @@ static void tcp_remove_sacks_gt(struct tcp_pcb *pcb, u32_t seq); @@ -49,7 +49,7 @@ index 0abee30..c20c9b5 100644 * The initial input processing of TCP. It verifies the TCP header, demultiplexes * the segment between the PCBs and passes it on to tcp_process(), which implements @@ -384,33 +414,15 @@ tcp_input(struct pbuf *p, struct netif *inp) - if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) { + if (ip_addr_eq(&lpcb->local_ip, ip_current_dest_addr())) { /* found an exact match */ #if GAZELLE_TCP_REUSE_IPPORT - // check master fd diff --git a/0068-enable-UDP-CKSUM-in-lwip.patch b/0068-enable-UDP-CKSUM-in-lwip.patch index 9f5d0d9..83db911 100644 --- a/0068-enable-UDP-CKSUM-in-lwip.patch +++ b/0068-enable-UDP-CKSUM-in-lwip.patch @@ -21,10 +21,10 @@ index b48c926..2c5b31e 100644 static inline u16_t ip_chksum_pseudo_offload(u8_t proto, u16_t proto_len, diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index f0df0e3..2ba1e4c 100644 +index 1c27051..f44b541 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h -@@ -180,6 +180,12 @@ +@@ -174,6 +174,12 @@ --------------------------------- */ #define LWIP_UDP 1 @@ -36,7 +36,7 @@ index f0df0e3..2ba1e4c 100644 + #define DEFAULT_UDP_RECVMBOX_SIZE 4096 - + /* -- 2.33.0 diff --git a/0070-add-CHECKSUM_UDP-when-not-support-OFFLOAD_UDP_CHECKS.patch b/0070-add-CHECKSUM_UDP-when-not-support-OFFLOAD_UDP_CHECKS.patch index 55b1779..446f649 100644 --- a/0070-add-CHECKSUM_UDP-when-not-support-OFFLOAD_UDP_CHECKS.patch +++ b/0070-add-CHECKSUM_UDP-when-not-support-OFFLOAD_UDP_CHECKS.patch @@ -12,7 +12,7 @@ Subject: [PATCH] add CHECKSUM_UDP when not support OFFLOAD_UDP_CHECKSUM 5 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 62a6511..5014a21 100644 +index d151a96..c906082 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -210,7 +210,7 @@ tcp_input(struct pbuf *p, struct netif *inp) @@ -25,7 +25,7 @@ index 62a6511..5014a21 100644 ret = (u64_t)ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, ip_current_src_addr(), ip_current_dest_addr()); diff --git a/src/core/udp.c b/src/core/udp.c -index 0b1fa65..d9db535 100644 +index 59e157d..06e21aa 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -412,9 +412,21 @@ udp_input(struct pbuf *p, struct netif *inp) @@ -81,7 +81,7 @@ index 0b1fa65..d9db535 100644 NETIF_RESET_HINTS(netif); diff --git a/src/include/dpdk_cksum.h b/src/include/dpdk_cksum.h -index 2c5b31e..d092a1d 100644 +index 2c5b31e..5b1b6f6 100644 --- a/src/include/dpdk_cksum.h +++ b/src/include/dpdk_cksum.h @@ -54,12 +54,12 @@ static inline u64_t is_cksum_ipbad(struct pbuf *p) { @@ -147,10 +147,10 @@ index 43b254a..c90ddb8 100644 #endif /* DPDK_VERSION_1911 */ diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index 2ba1e4c..5ba123f 100644 +index f44b541..d2ad30b 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h -@@ -71,18 +71,22 @@ +@@ -70,18 +70,22 @@ // rx cksum #define CHECKSUM_CHECK_IP 1 /* master switch */ #define CHECKSUM_CHECK_TCP 1 /* master switch */ @@ -173,8 +173,8 @@ index 2ba1e4c..5ba123f 100644 -#define CHECKSUM_OFFLOAD_ALL (CHECKSUM_GEN_IP_HW || CHECKSUM_GEN_TCP_HW || CHECKSUM_CHECK_IP_HW || CHECKSUM_CHECK_TCP_HW) +#define CHECKSUM_OFFLOAD_ALL (CHECKSUM_GEN_IP_HW || CHECKSUM_GEN_TCP_HW || CHECKSUM_CHECK_IP_HW || CHECKSUM_CHECK_TCP_HW || CHECKSUM_CHECK_UDP_HW || CHECKSUM_GEN_UDP_HW) - /* + --------------------------------------- -- 2.28.0.windows.1 diff --git a/0072-add-O_NONBLOCK-and-FIONBIO-when-not-defined.patch b/0072-add-O_NONBLOCK-and-FIONBIO-when-not-defined.patch index d4dda8b..7204336 100644 --- a/0072-add-O_NONBLOCK-and-FIONBIO-when-not-defined.patch +++ b/0072-add-O_NONBLOCK-and-FIONBIO-when-not-defined.patch @@ -1,8 +1,17 @@ +From 28922406bbe13f9442a16e4b1ccc19f42e8ebb9b Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 5 Feb 2024 17:26:46 +0800 +Subject: add O_NONBLOCK and FIONBIO when not defined + +--- + src/include/lwipopts.h | 4 ++++ + 1 file changed, 4 insertions(+) + diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index 5ba123f..baf739e 100644 +index d2ad30b..fbdcbf4 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h -@@ -244,9 +244,13 @@ +@@ -236,9 +236,13 @@ #define SO_REUSE 1 @@ -16,3 +25,6 @@ index 5ba123f..baf739e 100644 #define SIOCSHIWAT 1 +-- +2.33.0 + diff --git a/0074-gazelle-offloads-are-registered-to-lwip.patch b/0074-gazelle-offloads-are-registered-to-lwip.patch index 0bef4d8..0c9e865 100644 --- a/0074-gazelle-offloads-are-registered-to-lwip.patch +++ b/0074-gazelle-offloads-are-registered-to-lwip.patch @@ -16,7 +16,7 @@ Subject: [PATCH] gazelle offloads are registered to lwip 9 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/core/ipv4/icmp.c b/src/core/ipv4/icmp.c -index 402ba69..c3a877c 100644 +index 0a3b1c3..2984d24 100644 --- a/src/core/ipv4/icmp.c +++ b/src/core/ipv4/icmp.c @@ -241,7 +241,7 @@ icmp_input(struct pbuf *p, struct netif *inp) @@ -29,10 +29,10 @@ index 402ba69..c3a877c 100644 } else { iph_cksum_set(p, hlen, 0); diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c -index 1b70bb5..1e3690f 100644 +index 42f4bd5..4335423 100644 --- a/src/core/ipv4/ip4.c +++ b/src/core/ipv4/ip4.c -@@ -509,7 +509,7 @@ ip4_input(struct pbuf *p, struct netif *inp) +@@ -543,7 +543,7 @@ ip4_input(struct pbuf *p, struct netif *inp) IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) { #if CHECKSUM_CHECK_IP_HW u64_t ret; @@ -41,7 +41,7 @@ index 1b70bb5..1e3690f 100644 ret = is_cksum_ipbad(p); } else { ret = (u64_t)inet_chksum(iphdr, iphdr_hlen); -@@ -986,7 +986,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d +@@ -1020,7 +1020,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d #if CHECKSUM_GEN_IP IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { #if CHECKSUM_GEN_IP_HW @@ -50,7 +50,7 @@ index 1b70bb5..1e3690f 100644 iph_cksum_set(p, ip_hlen, 1); } else { iph_cksum_set(p, ip_hlen, 0); -@@ -1035,7 +1035,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d +@@ -1069,7 +1069,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d #if IP_FRAG /* don't fragment if interface has mtu set to 0 [loopif] */ #if GAZELLE_ENABLE @@ -60,7 +60,7 @@ index 1b70bb5..1e3690f 100644 if (netif->mtu && (p->tot_len > netif->mtu)) { return ip4_frag(p, netif, dest); diff --git a/src/core/ipv4/ip4_frag.c b/src/core/ipv4/ip4_frag.c -index e01ea51..f63a99e 100644 +index b2462d2..b594f29 100644 --- a/src/core/ipv4/ip4_frag.c +++ b/src/core/ipv4/ip4_frag.c @@ -642,7 +642,7 @@ ip4_reass(struct pbuf *p) @@ -82,10 +82,10 @@ index e01ea51..f63a99e 100644 } else { iph_cksum_set(p, IP_HLEN, 0); diff --git a/src/core/netif.c b/src/core/netif.c -index 86b74a0..eb59fbc 100644 +index db3c718..8a1ccec 100644 --- a/src/core/netif.c +++ b/src/core/netif.c -@@ -1049,6 +1049,26 @@ netif_set_link_down(struct netif *netif) +@@ -1085,6 +1085,26 @@ netif_set_link_down(struct netif *netif) } } @@ -113,7 +113,7 @@ index 86b74a0..eb59fbc 100644 /** * @ingroup netif diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 736845c..07203e5 100644 +index c906082..dcfb2b5 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -209,7 +209,7 @@ tcp_input(struct pbuf *p, struct netif *inp) @@ -126,10 +126,10 @@ index 736845c..07203e5 100644 } else { ret = (u64_t)ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c -index 547d01e..e2c9d63 100644 +index 65511ac..4bf3bfd 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c -@@ -1448,7 +1448,7 @@ tcp_output(struct tcp_pcb *pcb) +@@ -1451,7 +1451,7 @@ tcp_output(struct tcp_pcb *pcb) /* data available and window allows it to be sent? */ #if GAZELLE_ENABLE @@ -138,7 +138,7 @@ index 547d01e..e2c9d63 100644 uint16_t send_pkt = 0; do { -@@ -1831,7 +1831,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif +@@ -1834,7 +1834,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif #if CHECKSUM_GEN_TCP IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { #if CHECKSUM_GEN_TCP_HW @@ -147,9 +147,9 @@ index 547d01e..e2c9d63 100644 tcph_cksum_set(seg->p, TCPH_HDRLEN_BYTES(seg->tcphdr)); seg->tcphdr->chksum = ip_chksum_pseudo_offload(IP_PROTO_TCP,seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); } else { -@@ -2273,7 +2273,7 @@ tcp_output_control_segment(struct tcp_pcb *pcb, struct pbuf *p, - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { - struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload; +@@ -2293,7 +2293,7 @@ tcp_output_control_segment_netif(const struct tcp_pcb *pcb, struct pbuf *p, + IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { + struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload; #if CHECKSUM_GEN_TCP_HW - if (get_eth_params_tx_ol() & DEV_TX_OFFLOAD_TCP_CKSUM) { + if (netif_get_txol_flags(netif) & DEV_TX_OFFLOAD_TCP_CKSUM) { @@ -157,7 +157,7 @@ index 547d01e..e2c9d63 100644 tcphdr->chksum = ip_chksum_pseudo_offload(IP_PROTO_TCP, p->tot_len, src, dst); } else { diff --git a/src/core/udp.c b/src/core/udp.c -index 5c6dadb..937a045 100644 +index bac011a..ff20ced 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -414,7 +414,7 @@ udp_input(struct pbuf *p, struct netif *inp) @@ -192,7 +192,7 @@ index 5b1b6f6..b8056f9 100644 // for ip4_input static inline u64_t is_cksum_ipbad(struct pbuf *p) { diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h -index 057c51f..75f8d50 100644 +index 1e6dc46..502a151 100644 --- a/src/include/lwip/netif.h +++ b/src/include/lwip/netif.h @@ -106,6 +106,11 @@ extern "C" { @@ -207,7 +207,7 @@ index 057c51f..75f8d50 100644 /** * @} */ -@@ -343,6 +348,10 @@ struct netif { +@@ -352,6 +357,10 @@ struct netif { u8_t hwaddr_len; /** flags (@see @ref netif_flags) */ u8_t flags; @@ -217,8 +217,8 @@ index 057c51f..75f8d50 100644 +#endif /** descriptive abbreviation */ char name[2]; - /** number of this interface. Used for @ref if_api and @ref netifapi_netif, -@@ -464,6 +473,17 @@ void netif_set_down(struct netif *netif); + /** number of this interface. Used for @ref if_api and @ref netifapi_netif, +@@ -478,6 +487,17 @@ void netif_set_down(struct netif *netif); */ #define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0) diff --git a/0075-adapt-read-write-for-rtc-mode.patch b/0075-adapt-read-write-for-rtc-mode.patch index 9da5656..9609b38 100644 --- a/0075-adapt-read-write-for-rtc-mode.patch +++ b/0075-adapt-read-write-for-rtc-mode.patch @@ -15,10 +15,10 @@ Subject: [PATCH] adapt read/write for rtc mode 8 files changed, 174 insertions(+), 53 deletions(-) diff --git a/src/api/api_msg.c b/src/api/api_msg.c -index 3e982ab..d8b99ee 100644 +index 0f26119..2556901 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c -@@ -1753,11 +1753,15 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) +@@ -1754,11 +1754,15 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) write_more = 0; } #if GAZELLE_ENABLE @@ -40,10 +40,10 @@ index 3e982ab..d8b99ee 100644 #else err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); diff --git a/src/api/sockets.c b/src/api/sockets.c -index 8d573aa..e374f96 100644 +index 833b27f..a07fb59 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -1087,7 +1087,15 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) +@@ -1124,7 +1124,15 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) apiflags |= NETCONN_DONTBLOCK; } @@ -60,11 +60,10 @@ index 8d573aa..e374f96 100644 do { struct pbuf *p; err_t err; -@@ -1166,15 +1174,10 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) +@@ -1203,14 +1211,10 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) apiflags |= NETCONN_DONTBLOCK | NETCONN_NOFIN; /* @todo: do we need to support peeking more than one pbuf? */ } while ((recv_left > 0) && !(flags & MSG_PEEK)); -- -lwip_recv_tcp_done: -#else /* GAZELLE_ENABLE */ - LWIP_UNUSED_ARG(recv_left); @@ -73,19 +72,18 @@ index 8d573aa..e374f96 100644 - return recvd; +#if GAZELLE_ENABLE } --#endif /* GAZELLE_ENABLE */ -+#endif + #endif /* GAZELLE_ENABLE */ +lwip_recv_tcp_done: if (apiflags & NETCONN_NOAUTORCVD) { if ((recvd > 0) && !(flags & MSG_PEEK)) { /* ensure window update after copying all data */ diff --git a/src/core/init.c b/src/core/init.c -index 7b6214f..60e1c68 100644 +index 6841857..5b60ed8 100644 --- a/src/core/init.c +++ b/src/core/init.c -@@ -306,7 +306,7 @@ PACK_STRUCT_END - #if TCP_SNDLOWAT >= TCP_SND_BUF - #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +@@ -312,7 +312,7 @@ PACK_STRUCT_END + #if TCP_MSS >= ((16 * 1024) - 1) + #error "lwip_sanity_check: WARNING: TCP_MSS must be <= 16382 to prevent u16_t underflow in TCP_SNDLOWAT calculation!" #endif -#if TCP_SNDLOWAT >= (0xFFFFFFFF - (4 * TCP_MSS)) +#if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS)) @@ -93,7 +91,7 @@ index 7b6214f..60e1c68 100644 #endif #if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN diff --git a/src/core/pbuf.c b/src/core/pbuf.c -index 975e240..61690ff 100644 +index 3c04281..8386c90 100644 --- a/src/core/pbuf.c +++ b/src/core/pbuf.c @@ -117,6 +117,7 @@ pbuf_skip_const(const struct pbuf *in, u16_t in_offset, u16_t *out_offset); @@ -132,10 +130,10 @@ index 975e240..61690ff 100644 } case PBUF_RAM: { diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c -index e2c9d63..073d989 100644 +index 4bf3bfd..4e7aac0 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c -@@ -515,15 +515,18 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -518,15 +518,18 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) * pos records progress as data is segmented. */ @@ -155,7 +153,7 @@ index e2c9d63..073d989 100644 /* Usable space at the end of the last unsent segment */ unsent_optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(last_unsent->flags, pcb); -@@ -631,9 +634,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -634,9 +637,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) pcb->unsent_oversize == 0); #endif /* TCP_OVERSIZE */ } @@ -165,7 +163,7 @@ index e2c9d63..073d989 100644 /* * Phase 3: Create new segments. -@@ -651,7 +651,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -654,7 +654,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) u8_t chksum_swapped = 0; #endif /* TCP_CHECKSUM_ON_COPY */ @@ -173,7 +171,7 @@ index e2c9d63..073d989 100644 if (apiflags & TCP_WRITE_FLAG_COPY) { /* If copy is set, memory should be allocated and data copied * into pbuf */ -@@ -698,13 +697,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -701,13 +700,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) /* Concatenate the headers and data pbufs together. */ pbuf_cat(p/*header*/, p2/*data*/); } @@ -187,7 +185,7 @@ index e2c9d63..073d989 100644 queuelen += pbuf_clen(p); -@@ -714,14 +706,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -717,14 +709,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) if (queuelen > LWIP_MIN(TCP_SND_QUEUELEN, TCP_SNDQUEUELEN_OVERFLOW)) { LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n", queuelen, (int)TCP_SND_QUEUELEN)); @@ -202,7 +200,7 @@ index e2c9d63..073d989 100644 goto memerr; } -@@ -730,12 +715,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -733,12 +718,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) #endif if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { @@ -215,7 +213,7 @@ index e2c9d63..073d989 100644 goto memerr; } #if TCP_OVERSIZE_DBGCHECK -@@ -763,9 +742,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -766,9 +745,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); pos += seglen; @@ -225,7 +223,7 @@ index e2c9d63..073d989 100644 } /* -@@ -855,12 +831,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +@@ -858,12 +834,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) if (queue) { pcb->last_unsent = prev_seg; } @@ -239,7 +237,7 @@ index e2c9d63..073d989 100644 pcb->snd_queuelen = queuelen; LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", -@@ -880,14 +853,12 @@ memerr: +@@ -883,14 +856,12 @@ memerr: tcp_set_flags(pcb, TF_NAGLEMEMERR); TCP_STATS_INC(tcp.memerr); @@ -254,7 +252,7 @@ index e2c9d63..073d989 100644 if (pcb->snd_queuelen != 0) { LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL || pcb->unsent != NULL); -@@ -896,6 +867,137 @@ memerr: +@@ -899,6 +870,137 @@ memerr: return ERR_MEM; } @@ -392,7 +390,7 @@ index e2c9d63..073d989 100644 /** * Split segment on the head of the unsent queue. If return is not * ERR_OK, existing head remains intact -@@ -2095,6 +2197,7 @@ tcp_rexmit(struct tcp_pcb *pcb) +@@ -2098,6 +2200,7 @@ tcp_rexmit(struct tcp_pcb *pcb) /* Don't take any rtt measurements after retransmitting. */ pcb->rttest = 0; @@ -401,7 +399,7 @@ index e2c9d63..073d989 100644 /* Do the actual retransmission. */ MIB2_STATS_INC(mib2.tcpretranssegs); diff --git a/src/core/udp.c b/src/core/udp.c -index 937a045..828a489 100644 +index ff20ced..f38619b 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -414,7 +414,7 @@ udp_input(struct pbuf *p, struct netif *inp) @@ -414,10 +412,10 @@ index 937a045..828a489 100644 } else { ret = ip_chksum_pseudo(p, IP_PROTO_UDP, p->tot_len, diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h -index e13099c..959df3e 100644 +index f968441..460df21 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h -@@ -567,6 +567,10 @@ err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); +@@ -566,6 +566,10 @@ err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, u8_t apiflags); @@ -429,10 +427,10 @@ index e13099c..959df3e 100644 void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index baf739e..fdd4f87 100644 +index fbdcbf4..4ae37f5 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h -@@ -208,8 +208,8 @@ +@@ -201,8 +201,8 @@ #define TCP_LISTEN_BACKLOG 1 #define TCP_DEFAULT_LISTEN_BACKLOG 0xff @@ -443,7 +441,7 @@ index baf739e..fdd4f87 100644 #define TCP_MSS (FRAME_MTU - IP_HLEN - TCP_HLEN) -@@ -219,7 +219,7 @@ +@@ -212,7 +212,7 @@ #define TCP_SND_QUEUELEN (8191) diff --git a/0076-fix-recvmsg-return-EINVAL.patch b/0076-fix-recvmsg-return-EINVAL.patch index 32c2830..feeb411 100644 --- a/0076-fix-recvmsg-return-EINVAL.patch +++ b/0076-fix-recvmsg-return-EINVAL.patch @@ -8,10 +8,10 @@ Subject: [PATCH 76/77] fix recvmsg return EINVAL 1 file changed, 12 insertions(+) diff --git a/src/api/sockets.c b/src/api/sockets.c -index b6c7b05..1d71427 100644 +index a07fb59..575e298 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -1492,9 +1492,21 @@ lwip_recvmsg(int s, struct msghdr *message, int flags) +@@ -1535,9 +1535,21 @@ lwip_recvmsg(int s, struct msghdr *message, int flags) /* check for valid vectors */ buflen = 0; for (i = 0; i < message->msg_iovlen; i++) { @@ -30,7 +30,7 @@ index b6c7b05..1d71427 100644 +#else ((ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len) <= 0)) { +#endif - sock_set_errno(sock, err_to_errno(ERR_VAL)); + set_errno(err_to_errno(ERR_VAL)); done_socket(sock); return -1; -- diff --git a/0080-enable-ipv6.patch b/0080-enable-ipv6.patch index 1b75b4a..09e5ab6 100644 --- a/0080-enable-ipv6.patch +++ b/0080-enable-ipv6.patch @@ -23,10 +23,10 @@ Subject: [PATCH] enable ipv6 16 files changed, 107 insertions(+), 24 deletions(-) diff --git a/src/api/sockets.c b/src/api/sockets.c -index 6cff4cb..62052f2 100644 +index c4be6a8..6a9946a 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -113,6 +113,14 @@ +@@ -158,6 +158,14 @@ #endif /* LWIP_IPV4 */ #if LWIP_IPV6 @@ -39,9 +39,9 @@ index 6cff4cb..62052f2 100644 + (sin6)->sin6_scope_id = ip6_addr_zone(ipaddr); }while(0) +#else #define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipaddr, port) do { \ - (sin6)->sin6_len = sizeof(struct sockaddr_in6); \ + IP6ADDR_SOCKADDR_SET_LEN(sin6); \ (sin6)->sin6_family = AF_INET6; \ -@@ -120,6 +128,7 @@ +@@ -165,6 +173,7 @@ (sin6)->sin6_flowinfo = 0; \ inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipaddr); \ (sin6)->sin6_scope_id = ip6_addr_zone(ipaddr); }while(0) @@ -49,7 +49,7 @@ index 6cff4cb..62052f2 100644 #define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipaddr, port) do { \ inet6_addr_to_ip6addr(ip_2_ip6(ipaddr), &((sin6)->sin6_addr)); \ if (ip6_addr_has_scope(ip_2_ip6(ipaddr), IP6_UNKNOWN)) { \ -@@ -555,7 +564,8 @@ alloc_socket(struct netconn *newconn, int accepted, int flags) +@@ -595,7 +604,8 @@ alloc_socket(struct netconn *newconn, int accepted, int flags) LWIP_UNUSED_ARG(accepted); #if GAZELLE_ENABLE @@ -74,10 +74,10 @@ index 57a9670..69b43d1 100644 $(eval $(call register_dir, core, $(SRC))) diff --git a/src/core/init.c b/src/core/init.c -index 60e1c68..6880fd3 100644 +index 5b60ed8..36d7093 100644 --- a/src/core/init.c +++ b/src/core/init.c -@@ -347,7 +347,9 @@ lwip_init(void) +@@ -353,7 +353,9 @@ lwip_init(void) mem_init(); memp_init(); pbuf_init(); @@ -88,7 +88,7 @@ index 60e1c68..6880fd3 100644 ip_init(); #if LWIP_ARP diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c -index 9d904ec..101e599 100644 +index fad4f40..09b2f80 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -60,6 +60,10 @@ @@ -132,7 +132,7 @@ index 9d904ec..101e599 100644 LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n")); diff --git a/src/core/ipv6/ip6_frag.c b/src/core/ipv6/ip6_frag.c -index 8b352f5..67e36bf 100644 +index 16bcf95..5ff6724 100644 --- a/src/core/ipv6/ip6_frag.c +++ b/src/core/ipv6/ip6_frag.c @@ -689,6 +689,7 @@ ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p) @@ -162,7 +162,7 @@ index 8b352f5..67e36bf 100644 /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain * so that it is removed when pbuf_dechain is later called on rambuf. diff --git a/src/core/tcp.c b/src/core/tcp.c -index c44664e..963b8a4 100644 +index 34e99df..1d02574 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -1155,7 +1155,7 @@ tcp_new_port(void) @@ -175,7 +175,7 @@ index c44664e..963b8a4 100644 __atomic_store_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE); break; diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index ecbd616..7154659 100644 +index dcfb2b5..9b1ec9c 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -309,8 +309,8 @@ tcp_input(struct pbuf *p, struct netif *inp) @@ -190,10 +190,10 @@ index ecbd616..7154659 100644 head = &tcp_active_htable->array[idx].chain; tcppcb_hlist_for_each(pcb, node, head) { diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c -index 073d989..137e3cf 100644 +index 4e7aac0..a2d72b3 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c -@@ -139,7 +139,9 @@ static err_t tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct +@@ -142,7 +142,9 @@ static err_t tcp_output_control_segment_netif(const struct tcp_pcb *pcb, struct static struct netif * tcp_route(const struct tcp_pcb *pcb, const ip_addr_t *src, const ip_addr_t *dst) { @@ -204,7 +204,7 @@ index 073d989..137e3cf 100644 if ((pcb != NULL) && (pcb->netif_idx != NETIF_NO_INDEX)) { return netif_get_by_index(pcb->netif_idx); diff --git a/src/core/udp.c b/src/core/udp.c -index 828a489..727a705 100644 +index f38619b..02ffe36 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -132,7 +132,7 @@ udp_new_port(struct udp_pcb *dst_pcb) @@ -264,7 +264,7 @@ index c90ddb8..e61d0b3 100644 #define RTE_MBUF_F_TX_TCP_CKSUM PKT_TX_TCP_CKSUM #define RTE_MBUF_F_TX_TCP_SEG PKT_TX_TCP_SEG diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h -index ddae3fd..9b1341c 100644 +index 537683f..75c67ee 100644 --- a/src/include/lwip/priv/tcp_priv.h +++ b/src/include/lwip/priv/tcp_priv.h @@ -347,11 +347,24 @@ static inline int vdev_reg_done(enum reg_ring_type reg_type, const struct tcp_pc @@ -309,10 +309,10 @@ index ddae3fd..9b1341c 100644 hd = &htb->array[idx].chain; \ hlist_add_head(&(npcb)->tcp_node, hd); \ diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h -index cfec6a5..5715df4 100644 +index a50c691..89b6eb5 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h -@@ -88,7 +88,9 @@ struct sockaddr_in { +@@ -95,7 +95,9 @@ struct sockaddr_in { #if LWIP_IPV6 struct sockaddr_in6 { @@ -323,10 +323,10 @@ index cfec6a5..5715df4 100644 in_port_t sin6_port; /* Transport layer port # */ u32_t sin6_flowinfo; /* IPv6 flow information */ diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h -index 959df3e..91a86c9 100644 +index 460df21..bde17ec 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h -@@ -476,7 +476,26 @@ static inline unsigned int jhash_3words(unsigned int a, unsigned int b, unsigned +@@ -475,7 +475,26 @@ static inline unsigned int jhash_3words(unsigned int a, unsigned int b, unsigned return c; } @@ -355,12 +355,12 @@ index 959df3e..91a86c9 100644 #define tcppcb_hlist_for_each(tcppcb, node, list) \ hlist_for_each_entry(tcppcb, node, list, tcp_node) diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h -index a18179e..9ab5cde 100644 +index 985e13e..0c87c44 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h -@@ -178,6 +178,14 @@ - #define IP_HLEN 20 +@@ -172,6 +172,14 @@ + #define IP_HLEN 20 +/* + ------------------------------------- @@ -373,7 +373,7 @@ index a18179e..9ab5cde 100644 /* --------------------------------- ---------- UDP options ---------- -@@ -211,7 +219,7 @@ +@@ -204,7 +212,7 @@ #define TCP_OVERSIZE TCP_MSS #define LWIP_NETIF_TX_SINGLE_PBUF 1 @@ -382,7 +382,7 @@ index a18179e..9ab5cde 100644 #define TCP_WND (2500 * TCP_MSS) -@@ -263,5 +271,6 @@ +@@ -255,5 +263,6 @@ #define ETHARP_SUPPORT_VLAN 1 #define LWIP_VLAN_PCP 1 diff --git a/0081-ip6-hdr.patch b/0081-ip6-hdr.patch index a35fe54..cc7446d 100644 --- a/0081-ip6-hdr.patch +++ b/0081-ip6-hdr.patch @@ -1,7 +1,25 @@ -diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c ---- lwip-ipv6/src/core/ipv6/ip6.c 2023-11-15 19:48:02.864481010 +0800 -+++ lwip-ipv6-hdr/src/core/ipv6/ip6.c 2023-11-15 20:05:30.388481010 +0800 -@@ -367,7 +367,7 @@ +From 1a746c8c1c04d6ac39aa7b02d420cb0368baf08f Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 5 Feb 2024 17:34:46 +0800 +Subject: ip6 hdr + +--- + src/core/ipv6/ip6.c | 28 ++++++++++++++-------------- + src/core/ipv6/ip6_frag.c | 16 ++++++++-------- + src/core/ipv6/nd6.c | 10 +++++----- + src/core/raw.c | 2 +- + src/include/lwip/ip.h | 6 +++--- + src/include/lwip/ip6_frag.h | 2 +- + src/include/lwip/prot/ip6.h | 2 +- + src/netif/lowpan6.c | 4 ++-- + src/netif/lowpan6_common.c | 8 ++++---- + 9 files changed, 39 insertions(+), 39 deletions(-) + +diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c +index 09b2f80..5f16cd0 100644 +--- a/src/core/ipv6/ip6.c ++++ b/src/core/ipv6/ip6.c +@@ -367,7 +367,7 @@ ip6_select_source_address(struct netif *netif, const ip6_addr_t *dest) * @param inp the netif on which this packet was received */ static void @@ -10,7 +28,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c { struct netif *netif; -@@ -512,7 +512,7 @@ +@@ -512,7 +512,7 @@ ip6_input_accept(struct netif *netif) err_t ip6_input(struct pbuf *p, struct netif *inp) { @@ -19,7 +37,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c struct netif *netif; const u8_t *nexth; u16_t hlen, hlen_tot; /* the current header length */ -@@ -531,7 +531,7 @@ +@@ -531,7 +531,7 @@ ip6_input(struct pbuf *p, struct netif *inp) IP6_STATS_INC(ip6.recv); /* identify the IP header */ @@ -28,7 +46,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c if (IP6H_V(ip6hdr) != 6) { LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U32_F"\n", IP6H_V(ip6hdr))); -@@ -1015,7 +1015,7 @@ +@@ -1019,7 +1019,7 @@ netif_found: /* Returned p point to IPv6 header. * Update all our variables and pointers and continue. */ @@ -37,7 +55,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c nexth = &IP6H_NEXTH(ip6hdr); hlen = hlen_tot = IP6_HLEN; pbuf_remove_header(p, IP6_HLEN); -@@ -1188,7 +1188,7 @@ +@@ -1188,7 +1188,7 @@ ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, u8_t hl, u8_t tc, u8_t nexth, struct netif *netif) { @@ -46,7 +64,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c ip6_addr_t dest_addr; LWIP_ASSERT_CORE_LOCKED(); -@@ -1217,9 +1217,9 @@ +@@ -1217,9 +1217,9 @@ ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, return ERR_BUF; } @@ -59,7 +77,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c IP6H_HOPLIM_SET(ip6hdr, hl); IP6H_NEXTH_SET(ip6hdr, nexth); -@@ -1242,7 +1242,7 @@ +@@ -1242,7 +1242,7 @@ ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, } else { /* IP header already included in p */ @@ -68,7 +86,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest); ip6_addr_assign_zone(&dest_addr, IP6_UNKNOWN, netif); dest = &dest_addr; -@@ -1316,7 +1316,7 @@ +@@ -1316,7 +1316,7 @@ ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, u8_t hl, u8_t tc, u8_t nexth) { struct netif *netif; @@ -77,7 +95,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c ip6_addr_t src_addr, dest_addr; LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); -@@ -1325,7 +1325,7 @@ +@@ -1325,7 +1325,7 @@ ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, netif = ip6_route(src, dest); } else { /* IP header included in p, read addresses. */ @@ -86,7 +104,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c ip6_addr_copy_from_packed(src_addr, ip6hdr->src); ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest); netif = ip6_route(&src_addr, &dest_addr); -@@ -1375,7 +1375,7 @@ +@@ -1375,7 +1375,7 @@ ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, u8_t hl, u8_t tc, u8_t nexth, struct netif_hint *netif_hint) { struct netif *netif; @@ -95,7 +113,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c ip6_addr_t src_addr, dest_addr; err_t err; -@@ -1385,7 +1385,7 @@ +@@ -1385,7 +1385,7 @@ ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, netif = ip6_route(src, dest); } else { /* IP header included in p, read addresses. */ @@ -104,7 +122,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c ip6_addr_copy_from_packed(src_addr, ip6hdr->src); ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest); netif = ip6_route(&src_addr, &dest_addr); -@@ -1476,7 +1476,7 @@ +@@ -1476,7 +1476,7 @@ ip6_options_add_hbh_ra(struct pbuf *p, u8_t nexth, u8_t value) void ip6_debug_print(struct pbuf *p) { @@ -113,10 +131,11 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6.c lwip-ipv6-hdr/src/core/ipv6/ip6.c LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n")); LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); -diff -Nur lwip-ipv6/src/core/ipv6/ip6_frag.c lwip-ipv6-hdr/src/core/ipv6/ip6_frag.c ---- lwip-ipv6/src/core/ipv6/ip6_frag.c 2023-11-15 19:48:02.864481010 +0800 -+++ lwip-ipv6-hdr/src/core/ipv6/ip6_frag.c 2023-11-15 20:01:41.668481010 +0800 -@@ -551,7 +551,7 @@ +diff --git a/src/core/ipv6/ip6_frag.c b/src/core/ipv6/ip6_frag.c +index 5ff6724..78bcb2a 100644 +--- a/src/core/ipv6/ip6_frag.c ++++ b/src/core/ipv6/ip6_frag.c +@@ -551,7 +551,7 @@ ip6_reass(struct pbuf *p) if (valid) { /* All fragments have been received */ @@ -125,7 +144,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6_frag.c lwip-ipv6-hdr/src/core/ipv6/ip6_fra /* chain together the pbufs contained within the ip6_reassdata list. */ iprh = (struct ip6_reass_helper*) ipr->p->payload; -@@ -565,7 +565,7 @@ +@@ -565,7 +565,7 @@ ip6_reass(struct pbuf *p) pbuf_remove_header(next_pbuf, IP6_FRAG_HLEN); #if IPV6_FRAG_COPYHEADER if (IPV6_FRAG_REQROOM > 0) { @@ -134,7 +153,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6_frag.c lwip-ipv6-hdr/src/core/ipv6/ip6_fra u8_t hdrerr = pbuf_remove_header(next_pbuf, IPV6_FRAG_REQROOM); LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */ LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0); -@@ -610,7 +610,7 @@ +@@ -610,7 +610,7 @@ ip6_reass(struct pbuf *p) (size_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr)); /* This is where the IPv6 header is now. */ @@ -143,7 +162,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6_frag.c lwip-ipv6-hdr/src/core/ipv6/ip6_fra sizeof(struct ip6_frag_hdr)); /* Adjust datagram length by adding header lengths. */ -@@ -721,8 +721,8 @@ +@@ -721,8 +721,8 @@ ip6_frag_free_pbuf_custom(struct pbuf *p) err_t ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest) { @@ -154,7 +173,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6_frag.c lwip-ipv6-hdr/src/core/ipv6/ip6_fra struct ip6_frag_hdr *frag_hdr; struct pbuf *rambuf; #if !LWIP_NETIF_TX_SINGLE_PBUF -@@ -740,7 +740,7 @@ +@@ -740,7 +740,7 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest) identification++; @@ -163,7 +182,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6_frag.c lwip-ipv6-hdr/src/core/ipv6/ip6_fra /* @todo we assume there are no options in the unfragmentable part (IPv6 header). */ LWIP_ASSERT("p->tot_len >= IP6_HLEN", p->tot_len >= IP6_HLEN); -@@ -769,7 +769,7 @@ +@@ -769,7 +769,7 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest) } /* fill in the IP header */ SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); @@ -172,7 +191,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6_frag.c lwip-ipv6-hdr/src/core/ipv6/ip6_fra frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN); #else /* When not using a static buffer, create a chain of pbufs. -@@ -785,7 +785,7 @@ +@@ -785,7 +785,7 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest) LWIP_ASSERT("this needs a pbuf in one piece!", (rambuf->len >= (IP6_HLEN))); SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); @@ -181,10 +200,11 @@ diff -Nur lwip-ipv6/src/core/ipv6/ip6_frag.c lwip-ipv6-hdr/src/core/ipv6/ip6_fra frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN); /* Can just adjust p directly for needed offset. */ -diff -Nur lwip-ipv6/src/core/ipv6/nd6.c lwip-ipv6-hdr/src/core/ipv6/nd6.c ---- lwip-ipv6/src/core/ipv6/nd6.c 2023-11-15 19:48:02.864481010 +0800 -+++ lwip-ipv6-hdr/src/core/ipv6/nd6.c 2023-11-15 20:06:47.036481010 +0800 -@@ -895,7 +895,7 @@ +diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c +index 3b13c21..970ce40 100644 +--- a/src/core/ipv6/nd6.c ++++ b/src/core/ipv6/nd6.c +@@ -910,7 +910,7 @@ nd6_input(struct pbuf *p, struct netif *inp) case ICMP6_TYPE_PTB: /* Packet too big */ { struct icmp6_hdr *icmp6hdr; /* Packet too big message */ @@ -193,7 +213,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/nd6.c lwip-ipv6-hdr/src/core/ipv6/nd6.c u32_t pmtu; ip6_addr_t destination_address; -@@ -909,7 +909,7 @@ +@@ -924,7 +924,7 @@ nd6_input(struct pbuf *p, struct netif *inp) } icmp6hdr = (struct icmp6_hdr *)p->payload; @@ -202,7 +222,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/nd6.c lwip-ipv6-hdr/src/core/ipv6/nd6.c /* Create an aligned, zoned copy of the destination address. */ ip6_addr_copy_from_packed(destination_address, ip6hdr->dest); -@@ -2187,7 +2187,7 @@ +@@ -2212,7 +2212,7 @@ nd6_free_q(struct nd6_q_entry *q) static void nd6_send_q(s8_t i) { @@ -211,7 +231,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/nd6.c lwip-ipv6-hdr/src/core/ipv6/nd6.c ip6_addr_t dest; #if LWIP_ND6_QUEUEING struct nd6_q_entry *q; -@@ -2204,7 +2204,7 @@ +@@ -2229,7 +2229,7 @@ nd6_send_q(s8_t i) /* pop first item off the queue */ neighbor_cache[i].q = q->next; /* Get ipv6 header. */ @@ -220,7 +240,7 @@ diff -Nur lwip-ipv6/src/core/ipv6/nd6.c lwip-ipv6-hdr/src/core/ipv6/nd6.c /* Create an aligned copy. */ ip6_addr_copy_from_packed(dest, ip6hdr->dest); /* Restore the zone, if applicable. */ -@@ -2219,7 +2219,7 @@ +@@ -2245,7 +2245,7 @@ nd6_send_q(s8_t i) #else /* LWIP_ND6_QUEUEING */ if (neighbor_cache[i].q != NULL) { /* Get ipv6 header. */ @@ -229,10 +249,11 @@ diff -Nur lwip-ipv6/src/core/ipv6/nd6.c lwip-ipv6-hdr/src/core/ipv6/nd6.c /* Create an aligned copy. */ ip6_addr_copy_from_packed(dest, ip6hdr->dest); /* Restore the zone, if applicable. */ -diff -Nur lwip-ipv6/src/core/raw.c lwip-ipv6-hdr/src/core/raw.c ---- lwip-ipv6/src/core/raw.c 2023-11-15 19:48:02.860481010 +0800 -+++ lwip-ipv6-hdr/src/core/raw.c 2023-11-15 19:49:53.468481010 +0800 -@@ -146,7 +146,7 @@ +diff --git a/src/core/raw.c b/src/core/raw.c +index d85aaec..27f990d 100644 +--- a/src/core/raw.c ++++ b/src/core/raw.c +@@ -146,7 +146,7 @@ raw_input(struct pbuf *p, struct netif *inp) if (IP_HDR_GET_VERSION(p->payload) == 6) #endif /* LWIP_IPV4 */ { @@ -241,22 +262,11 @@ diff -Nur lwip-ipv6/src/core/raw.c lwip-ipv6-hdr/src/core/raw.c proto = IP6H_NEXTH(ip6hdr); } #if LWIP_IPV4 -diff -Nur lwip-ipv6/src/include/lwip/ip6_frag.h lwip-ipv6-hdr/src/include/lwip/ip6_frag.h ---- lwip-ipv6/src/include/lwip/ip6_frag.h 2023-11-15 19:48:02.864481010 +0800 -+++ lwip-ipv6-hdr/src/include/lwip/ip6_frag.h 2023-11-15 20:13:40.008481010 +0800 -@@ -90,7 +90,7 @@ - struct ip6_reassdata { - struct ip6_reassdata *next; - struct pbuf *p; -- struct ip6_hdr *iphdr; /* pointer to the first (original) IPv6 header */ -+ struct ip6hdr *iphdr; /* pointer to the first (original) IPv6 header */ - #if IPV6_FRAG_COPYHEADER - ip6_addr_p_t src; /* copy of the source address in the IP header */ - ip6_addr_p_t dest; /* copy of the destination address in the IP header */ -diff -Nur lwip-ipv6/src/include/lwip/ip.h lwip-ipv6-hdr/src/include/lwip/ip.h ---- lwip-ipv6/src/include/lwip/ip.h 2023-11-15 19:48:02.864481010 +0800 -+++ lwip-ipv6-hdr/src/include/lwip/ip.h 2023-11-15 20:12:42.796481010 +0800 -@@ -123,7 +123,7 @@ +diff --git a/src/include/lwip/ip.h b/src/include/lwip/ip.h +index b6ab031..dd25ce6 100644 +--- a/src/include/lwip/ip.h ++++ b/src/include/lwip/ip.h +@@ -134,7 +134,7 @@ struct ip_globals #endif /* LWIP_IPV4 */ #if LWIP_IPV6 /** Header of the input IPv6 packet currently being processed. */ @@ -265,7 +275,7 @@ diff -Nur lwip-ipv6/src/include/lwip/ip.h lwip-ipv6-hdr/src/include/lwip/ip.h #endif /* LWIP_IPV6 */ /** Total header length of current_ip4/6_header (i.e. after this, the UDP/TCP header starts) */ u16_t current_ip_header_tot_len; -@@ -159,7 +159,7 @@ +@@ -170,7 +170,7 @@ extern PER_THREAD struct ip_globals ip_data; /** Get the IPv6 header of the current packet. * This function must only be called from a receive callback (udp_recv, * raw_recv, tcp_accept). It will return NULL otherwise. */ @@ -274,7 +284,7 @@ diff -Nur lwip-ipv6/src/include/lwip/ip.h lwip-ipv6-hdr/src/include/lwip/ip.h /** Returns TRUE if the current IP input packet is IPv6, FALSE if it is IPv4 */ #define ip_current_is_v6() (ip6_current_header() != NULL) /** Source IPv6 address of current_header */ -@@ -201,7 +201,7 @@ +@@ -212,7 +212,7 @@ extern PER_THREAD struct ip_globals ip_data; /** Get the IPv6 header of the current packet. * This function must only be called from a receive callback (udp_recv, * raw_recv, tcp_accept). It will return NULL otherwise. */ @@ -283,10 +293,24 @@ diff -Nur lwip-ipv6/src/include/lwip/ip.h lwip-ipv6-hdr/src/include/lwip/ip.h /** Always returns TRUE when only supporting IPv6 only */ #define ip_current_is_v6() 1 /** Get the transport layer protocol */ -diff -Nur lwip-ipv6/src/include/lwip/prot/ip6.h lwip-ipv6-hdr/src/include/lwip/prot/ip6.h ---- lwip-ipv6/src/include/lwip/prot/ip6.h 2023-11-15 19:48:02.868481010 +0800 -+++ lwip-ipv6-hdr/src/include/lwip/prot/ip6.h 2023-11-17 13:24:56.832481010 +0800 -@@ -79,7 +79,7 @@ +diff --git a/src/include/lwip/ip6_frag.h b/src/include/lwip/ip6_frag.h +index 87e0e86..6ea6052 100644 +--- a/src/include/lwip/ip6_frag.h ++++ b/src/include/lwip/ip6_frag.h +@@ -90,7 +90,7 @@ extern "C" { + struct ip6_reassdata { + struct ip6_reassdata *next; + struct pbuf *p; +- struct ip6_hdr *iphdr; /* pointer to the first (original) IPv6 header */ ++ struct ip6hdr *iphdr; /* pointer to the first (original) IPv6 header */ + #if IPV6_FRAG_COPYHEADER + ip6_addr_p_t src; /* copy of the source address in the IP header */ + ip6_addr_p_t dest; /* copy of the destination address in the IP header */ +diff --git a/src/include/lwip/prot/ip6.h b/src/include/lwip/prot/ip6.h +index 7df81ed..40f270b 100644 +--- a/src/include/lwip/prot/ip6.h ++++ b/src/include/lwip/prot/ip6.h +@@ -79,7 +79,7 @@ typedef struct ip6_addr_packed ip6_addr_p_t; # include "arch/bpstruct.h" #endif PACK_STRUCT_BEGIN @@ -295,10 +319,11 @@ diff -Nur lwip-ipv6/src/include/lwip/prot/ip6.h lwip-ipv6-hdr/src/include/lwip/p /** version / traffic class / flow label */ PACK_STRUCT_FIELD(u32_t _v_tc_fl); /** payload length */ -diff -Nur lwip-ipv6/src/netif/lowpan6.c lwip-ipv6-hdr/src/netif/lowpan6.c ---- lwip-ipv6/src/netif/lowpan6.c 2023-11-15 19:48:02.868481010 +0800 -+++ lwip-ipv6-hdr/src/netif/lowpan6.c 2023-11-15 20:16:23.836481010 +0800 -@@ -570,12 +570,12 @@ +diff --git a/src/netif/lowpan6.c b/src/netif/lowpan6.c +index 8eb751c..037ac6d 100644 +--- a/src/netif/lowpan6.c ++++ b/src/netif/lowpan6.c +@@ -571,12 +571,12 @@ lowpan6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr) struct lowpan6_link_addr src, dest; #if LWIP_6LOWPAN_INFER_SHORT_ADDRESS ip6_addr_t ip6_src; @@ -313,10 +338,11 @@ diff -Nur lwip-ipv6/src/netif/lowpan6.c lwip-ipv6-hdr/src/netif/lowpan6.c ip6_addr_copy_from_packed(ip6_src, ip6_hdr->src); ip6_addr_assign_zone(&ip6_src, IP6_UNICAST, netif); if (lowpan6_get_address_mode(&ip6_src, &short_mac_addr) == 3) { -diff -Nur lwip-ipv6/src/netif/lowpan6_common.c lwip-ipv6-hdr/src/netif/lowpan6_common.c ---- lwip-ipv6/src/netif/lowpan6_common.c 2023-11-15 19:48:02.868481010 +0800 -+++ lwip-ipv6-hdr/src/netif/lowpan6_common.c 2023-11-15 20:15:44.460481010 +0800 -@@ -137,7 +137,7 @@ +diff --git a/src/netif/lowpan6_common.c b/src/netif/lowpan6_common.c +index 9f50658..7b9f834 100644 +--- a/src/netif/lowpan6_common.c ++++ b/src/netif/lowpan6_common.c +@@ -137,7 +137,7 @@ lowpan6_compress_headers(struct netif *netif, u8_t *inbuf, size_t inbuf_size, u8 u8_t lowpan6_header_len; u8_t hidden_header_len = 0; s8_t i; @@ -325,7 +351,7 @@ diff -Nur lwip-ipv6/src/netif/lowpan6_common.c lwip-ipv6-hdr/src/netif/lowpan6_c ip_addr_t ip6src, ip6dst; LWIP_ASSERT("netif != NULL", netif != NULL); -@@ -160,7 +160,7 @@ +@@ -160,7 +160,7 @@ lowpan6_compress_headers(struct netif *netif, u8_t *inbuf, size_t inbuf_size, u8 } /* Point to ip6 header and align copies of src/dest addresses. */ @@ -334,7 +360,7 @@ diff -Nur lwip-ipv6/src/netif/lowpan6_common.c lwip-ipv6-hdr/src/netif/lowpan6_c ip_addr_copy_from_ip6_packed(ip6dst, ip6hdr->dest); ip6_addr_assign_zone(ip_2_ip6(&ip6dst), IP6_UNKNOWN, netif); ip_addr_copy_from_ip6_packed(ip6src, ip6hdr->src); -@@ -396,7 +396,7 @@ +@@ -396,7 +396,7 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize, struct lowpan6_link_addr *src, struct lowpan6_link_addr *dest) { u16_t lowpan6_offset; @@ -343,7 +369,7 @@ diff -Nur lwip-ipv6/src/netif/lowpan6_common.c lwip-ipv6-hdr/src/netif/lowpan6_c s8_t i; u32_t header_temp; u16_t ip6_offset = IP6_HLEN; -@@ -408,7 +408,7 @@ +@@ -408,7 +408,7 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize, LWIP_ASSERT("hdr_size_comp != NULL", hdr_size_comp != NULL); LWIP_ASSERT("dehdr_size_decompst != NULL", hdr_size_decomp != NULL); @@ -352,3 +378,6 @@ diff -Nur lwip-ipv6/src/netif/lowpan6_common.c lwip-ipv6-hdr/src/netif/lowpan6_c if (decomp_bufsize < IP6_HLEN) { return ERR_MEM; } +-- +2.33.0 + diff --git a/0082-add-vlanid-in-netif.patch b/0082-add-vlanid-in-netif.patch index 49bffd3..7744f7e 100644 --- a/0082-add-vlanid-in-netif.patch +++ b/0082-add-vlanid-in-netif.patch @@ -1,9 +1,23 @@ -diff -Nur lwip-org/src/core/netif.c lwip-vlan/src/core/netif.c ---- lwip-org/src/core/netif.c 2023-11-24 17:38:29.428481010 +0800 -+++ lwip-vlan/src/core/netif.c 2023-11-27 18:35:00.172481010 +0800 -@@ -355,6 +355,11 @@ - netif->input = input; - +From 95f00d7a735b20cf352f6712529547b3720614cb Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 5 Feb 2024 17:35:32 +0800 +Subject: add vlanid in netif + +--- + src/core/netif.c | 14 ++++++++++++++ + src/core/tcp.c | 2 ++ + src/core/tcp_in.c | 2 ++ + src/include/lwip/netif.h | 9 +++++++++ + src/netif/ethernet.c | 6 ++++++ + 5 files changed, 33 insertions(+) + +diff --git a/src/core/netif.c b/src/core/netif.c +index 8a1ccec..eff3cae 100644 +--- a/src/core/netif.c ++++ b/src/core/netif.c +@@ -369,6 +369,11 @@ netif_add(struct netif *netif, + netif->acd_list = NULL; + #endif /* LWIP_ACD */ NETIF_RESET_HINTS(netif); + +#if GAZELLE_ENABLE @@ -13,7 +27,7 @@ diff -Nur lwip-org/src/core/netif.c lwip-vlan/src/core/netif.c #if ENABLE_LOOPBACK netif->loop_first = NULL; netif->loop_last = NULL; -@@ -441,6 +446,15 @@ +@@ -455,6 +460,15 @@ netif_add(struct netif *netif, return netif; } @@ -29,23 +43,25 @@ diff -Nur lwip-org/src/core/netif.c lwip-vlan/src/core/netif.c static void netif_do_ip_addr_changed(const ip_addr_t *old_addr, const ip_addr_t *new_addr) { -diff -Nur lwip-org/src/core/tcp.c lwip-vlan/src/core/tcp.c ---- lwip-org/src/core/tcp.c 2023-11-24 17:38:29.448481010 +0800 -+++ lwip-vlan/src/core/tcp.c 2023-11-27 10:42:33.228481010 +0800 -@@ -987,7 +987,9 @@ - lpcb->tos = pcb->tos; +diff --git a/src/core/tcp.c b/src/core/tcp.c +index 1d02574..b889a4e 100644 +--- a/src/core/tcp.c ++++ b/src/core/tcp.c +@@ -996,7 +996,9 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) + #endif #if LWIP_VLAN_PCP +#if !GAZELLE_ENABLE lpcb->netif_hints.tci = pcb->netif_hints.tci; +#endif #endif /* LWIP_VLAN_PCP */ - #if GAZELLE_TCP_REUSE_IPPORT - lpcb->connect_num = 0; -diff -Nur lwip-org/src/core/tcp_in.c lwip-vlan/src/core/tcp_in.c ---- lwip-org/src/core/tcp_in.c 2023-11-24 17:38:29.448481010 +0800 -+++ lwip-vlan/src/core/tcp_in.c 2023-11-27 10:42:33.228481010 +0800 -@@ -808,7 +808,9 @@ + #if LWIP_IPV4 && LWIP_IPV6 + IP_SET_TYPE_VAL(lpcb->remote_ip, pcb->local_ip.type); +diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c +index 9b1ec9c..10f8a14 100644 +--- a/src/core/tcp_in.c ++++ b/src/core/tcp_in.c +@@ -808,7 +808,9 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) npcb->listener = pcb; #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ #if LWIP_VLAN_PCP @@ -55,9 +71,10 @@ diff -Nur lwip-org/src/core/tcp_in.c lwip-vlan/src/core/tcp_in.c #endif /* LWIP_VLAN_PCP */ /* inherit socket options */ npcb->so_options = pcb->so_options & SOF_INHERITED; -diff -Nur lwip-org/src/include/lwip/netif.h lwip-vlan/src/include/lwip/netif.h ---- lwip-org/src/include/lwip/netif.h 2023-11-24 17:38:29.440481010 +0800 -+++ lwip-vlan/src/include/lwip/netif.h 2023-11-27 18:33:07.936481010 +0800 +diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h +index 502a151..368b89a 100644 +--- a/src/include/lwip/netif.h ++++ b/src/include/lwip/netif.h @@ -45,6 +45,10 @@ #include "lwip/ip_addr.h" @@ -69,7 +86,7 @@ diff -Nur lwip-org/src/include/lwip/netif.h lwip-vlan/src/include/lwip/netif.h #include "lwip/def.h" #include "lwip/pbuf.h" #include "lwip/stats.h" -@@ -357,6 +361,10 @@ +@@ -360,6 +364,10 @@ struct netif { #if GAZELLE_ENABLE u64_t rxol_flags; u64_t txol_flags; @@ -80,7 +97,7 @@ diff -Nur lwip-org/src/include/lwip/netif.h lwip-vlan/src/include/lwip/netif.h #endif /** descriptive abbreviation */ char name[2]; -@@ -484,6 +492,7 @@ +@@ -492,6 +500,7 @@ void netif_set_down(struct netif *netif); #define netif_get_rxol_flags(netif) ((netif)->rxol_flags) #define netif_get_txol_flags(netif) ((netif)->txol_flags) @@ -88,10 +105,11 @@ diff -Nur lwip-org/src/include/lwip/netif.h lwip-vlan/src/include/lwip/netif.h void netif_set_rtc_mode(struct netif *netif); void netif_set_rxol_flags(struct netif *netif, u64_t flags); void netif_set_txol_flags(struct netif *netif, u64_t flags); -diff -Nur lwip-org/src/netif/ethernet.c lwip-vlan/src/netif/ethernet.c ---- lwip-org/src/netif/ethernet.c 2023-11-24 17:38:29.444481010 +0800 -+++ lwip-vlan/src/netif/ethernet.c 2023-11-27 11:07:48.464481010 +0800 -@@ -283,9 +283,15 @@ +diff --git a/src/netif/ethernet.c b/src/netif/ethernet.c +index dc89566..af4cffc 100644 +--- a/src/netif/ethernet.c ++++ b/src/netif/ethernet.c +@@ -283,9 +283,15 @@ ethernet_output(struct netif * netif, struct pbuf * p, vlan_prio_vid = LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type); #elif LWIP_VLAN_PCP vlan_prio_vid = -1; @@ -107,3 +125,5 @@ diff -Nur lwip-org/src/netif/ethernet.c lwip-vlan/src/netif/ethernet.c #endif if (vlan_prio_vid >= 0) { struct eth_vlan_hdr *vlanhdr; +-- +2.33.0 diff --git a/0085-add-lwip-log-tcp_rst-tcp_abandon-tcp_abort.patch b/0085-add-lwip-log-tcp_rst-tcp_abandon-tcp_abort.patch index 0785dbf..f5808fa 100644 --- a/0085-add-lwip-log-tcp_rst-tcp_abandon-tcp_abort.patch +++ b/0085-add-lwip-log-tcp_rst-tcp_abandon-tcp_abort.patch @@ -10,7 +10,7 @@ Subject: [PATCH] add lwip log: tcp_rst & tcp_abandon & tcp_abort 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/core/tcp.c b/src/core/tcp.c -index 963b8a4..a4f82a3 100644 +index f6c4cf1..73d1d1e 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -415,6 +415,9 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) @@ -33,7 +33,7 @@ index 963b8a4..a4f82a3 100644 tcp_rst(pcb, seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port); } last_state = pcb->state; -@@ -1574,6 +1578,9 @@ tcp_slowtmr_start: +@@ -1577,6 +1581,9 @@ tcp_slowtmr_start: #endif if (pcb_reset) { @@ -43,7 +43,7 @@ index 963b8a4..a4f82a3 100644 tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port); } -@@ -1941,8 +1948,8 @@ tcp_kill_prio(u8_t prio) +@@ -1947,8 +1954,8 @@ tcp_kill_prio(u8_t prio) } } if (inactive != NULL) { @@ -54,7 +54,7 @@ index 963b8a4..a4f82a3 100644 tcp_abort(inactive); } } -@@ -1972,8 +1979,8 @@ tcp_kill_state(enum tcp_state state) +@@ -1978,8 +1985,8 @@ tcp_kill_state(enum tcp_state state) } } if (inactive != NULL) { @@ -65,7 +65,7 @@ index 963b8a4..a4f82a3 100644 /* Don't send a RST, since no data is lost. */ tcp_abandon(inactive, 0); } -@@ -1999,8 +2006,8 @@ tcp_kill_timewait(void) +@@ -2005,8 +2012,8 @@ tcp_kill_timewait(void) } } if (inactive != NULL) { @@ -76,7 +76,7 @@ index 963b8a4..a4f82a3 100644 tcp_abort(inactive); } } -@@ -2540,7 +2547,8 @@ tcp_netif_ip_addr_changed_pcblist(const ip_addr_t *old_addr, struct tcp_pcb *pcb +@@ -2548,7 +2555,8 @@ tcp_netif_ip_addr_changed_pcblist(const ip_addr_t *old_addr, struct tcp_pcb *pcb ) { /* this connection must be aborted */ struct tcp_pcb *next = pcb->next; @@ -87,7 +87,7 @@ index 963b8a4..a4f82a3 100644 pcb = next; } else { diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 7154659..700a64c 100644 +index 10f8a14..4755ab5 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -592,6 +592,7 @@ tcp_input(struct pbuf *p, struct netif *inp) @@ -109,7 +109,7 @@ index 7154659..700a64c 100644 + LWIP_DEBUGF(TCP_RST_DEBUG | GAZELLE_DEBUG_SERIOUS, + ("tcp_input: no PCB match found, send RST, dest port=%d, src port=%d\n", + lwip_ntohs(tcphdr->dest), lwip_ntohs(tcphdr->src))); - tcp_rst(NULL, ackno, seqno + tcplen, ip_current_dest_addr(), + tcp_rst_netif(ip_data.current_input_netif, ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); } @@ -761,7 +764,9 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) @@ -120,10 +120,10 @@ index 7154659..700a64c 100644 + LWIP_DEBUGF(TCP_RST_DEBUG | GAZELLE_DEBUG_SERIOUS, + ("tcp_listen_input: ACK in LISTEN, send reset, dest port=%d, src port=%d\n", + lwip_ntohs(tcphdr->dest), lwip_ntohs(tcphdr->src))); - tcp_rst((const struct tcp_pcb *)pcb, ackno, seqno + tcplen, ip_current_dest_addr(), + tcp_rst_netif(ip_data.current_input_netif, ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); } else if (flags & TCP_SYN) { -@@ -852,6 +857,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) +@@ -854,6 +859,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) /* Send a SYN|ACK together with the MSS option. */ rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK); if (rc != ERR_OK) { @@ -131,7 +131,7 @@ index 7154659..700a64c 100644 tcp_abandon(npcb, 0); PERF_RESUME(PERF_LAYER_TCP, PERF_POINT_TCP_SYN_RECV); return; -@@ -892,6 +898,9 @@ tcp_timewait_input(struct tcp_pcb *pcb) +@@ -894,6 +900,9 @@ tcp_timewait_input(struct tcp_pcb *pcb) should be sent in reply */ if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd)) { /* If the SYN is in the window it is an error, send a reset */ @@ -141,7 +141,7 @@ index 7154659..700a64c 100644 tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); return; -@@ -1060,6 +1069,8 @@ tcp_process(struct tcp_pcb *pcb) +@@ -1062,6 +1071,8 @@ tcp_process(struct tcp_pcb *pcb) /* received ACK? possibly a half-open connection */ else if (flags & TCP_ACK) { /* send a RST to bring the other side in a non-synchronized state. */ @@ -150,7 +150,7 @@ index 7154659..700a64c 100644 tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); /* Resend SYN immediately (don't wait for rto timeout) to establish -@@ -1102,6 +1113,7 @@ tcp_process(struct tcp_pcb *pcb) +@@ -1104,6 +1115,7 @@ tcp_process(struct tcp_pcb *pcb) * the connection. */ /* Already aborted? */ if (err != ERR_ABRT) { @@ -158,7 +158,7 @@ index 7154659..700a64c 100644 tcp_abort(pcb); } return ERR_ABRT; -@@ -1129,6 +1141,9 @@ tcp_process(struct tcp_pcb *pcb) +@@ -1131,6 +1143,9 @@ tcp_process(struct tcp_pcb *pcb) } } else { /* incorrect ACK number, send RST */ @@ -169,7 +169,7 @@ index 7154659..700a64c 100644 ip_current_src_addr(), tcphdr->dest, tcphdr->src); } diff --git a/src/include/lwip/debug.h b/src/include/lwip/debug.h -index f47cbfe..6abed9f 100644 +index 4986973..c2de064 100644 --- a/src/include/lwip/debug.h +++ b/src/include/lwip/debug.h @@ -56,12 +56,12 @@ @@ -189,4 +189,3 @@ index f47cbfe..6abed9f 100644 -- 2.23.0 - diff --git a/0087-support-vlan-offload.patch b/0087-support-vlan-offload.patch index 756db5d..7703028 100644 --- a/0087-support-vlan-offload.patch +++ b/0087-support-vlan-offload.patch @@ -1,18 +1,31 @@ -diff -Nur lwip-82/src/include/dpdk_version.h lwip-offload/src/include/dpdk_version.h ---- lwip-82/src/include/dpdk_version.h 2023-11-28 14:17:02.432481010 +0800 -+++ lwip-offload/src/include/dpdk_version.h 2023-11-28 14:34:21.208481010 +0800 +From c2c63406f804550db5670715c1afa6e743d1f675 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 5 Feb 2024 17:38:06 +0800 +Subject: support vlan offload + +--- + src/include/dpdk_version.h | 1 + + src/include/lwip/pbuf.h | 1 + + src/netif/ethernet.c | 17 +++++++++++------ + 3 files changed, 13 insertions(+), 6 deletions(-) + +diff --git a/src/include/dpdk_version.h b/src/include/dpdk_version.h +index e61d0b3..5efaa39 100644 +--- a/src/include/dpdk_version.h ++++ b/src/include/dpdk_version.h @@ -48,6 +48,7 @@ #define RTE_MBUF_F_TX_TCP_CKSUM PKT_TX_TCP_CKSUM #define RTE_MBUF_F_TX_TCP_SEG PKT_TX_TCP_SEG #define RTE_MBUF_F_TX_UDP_CKSUM PKT_TX_UDP_CKSUM +#define RTE_MBUF_F_TX_VLAN PKT_TX_VLAN_PKT - + #endif /* DPDK_VERSION_1911 */ - -diff -Nur lwip-82/src/include/lwip/pbuf.h lwip-offload/src/include/lwip/pbuf.h ---- lwip-82/src/include/lwip/pbuf.h 2023-11-28 14:17:02.408481010 +0800 -+++ lwip-offload/src/include/lwip/pbuf.h 2023-11-28 14:41:31.580481010 +0800 -@@ -240,6 +240,7 @@ + +diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h +index 7fad719..bc29372 100644 +--- a/src/include/lwip/pbuf.h ++++ b/src/include/lwip/pbuf.h +@@ -240,6 +240,7 @@ struct pbuf { struct pbuf *last; pthread_spinlock_t pbuf_lock; struct tcp_pcb *pcb; @@ -20,10 +33,11 @@ diff -Nur lwip-82/src/include/lwip/pbuf.h lwip-offload/src/include/lwip/pbuf.h #if GAZELLE_UDP_ENABLE ip_addr_t addr; u16_t port; -diff -Nur lwip-82/src/netif/ethernet.c lwip-offload/src/netif/ethernet.c ---- lwip-82/src/netif/ethernet.c 2023-11-28 14:17:02.440481010 +0800 -+++ lwip-offload/src/netif/ethernet.c 2023-11-28 16:35:36.536481010 +0800 -@@ -289,7 +289,12 @@ +diff --git a/src/netif/ethernet.c b/src/netif/ethernet.c +index af4cffc..d2960b5 100644 +--- a/src/netif/ethernet.c ++++ b/src/netif/ethernet.c +@@ -289,7 +289,12 @@ ethernet_output(struct netif * netif, struct pbuf * p, } #else if (netif->vlan_enable) { @@ -37,9 +51,9 @@ diff -Nur lwip-82/src/netif/ethernet.c lwip-offload/src/netif/ethernet.c } #endif /* GAZELLE_ENABLE */ #endif -@@ -327,11 +332,11 @@ +@@ -327,11 +332,11 @@ ethernet_output(struct netif * netif, struct pbuf * p, ("ethernet_output: sending packet %p\n", (void *)p)); - + #if CHECKSUM_GEN_IP_HW || CHECKSUM_GEN_TCP_HW -#if LWIP_VLAN_PCP - ethh_cksum_set(p, sizeof(*ethhdr)+SIZEOF_VLAN_HDR); @@ -52,5 +66,7 @@ diff -Nur lwip-82/src/netif/ethernet.c lwip-offload/src/netif/ethernet.c + ethh_cksum_set(p, sizeof(*ethhdr)); + } #endif - + /* send the packet */ +-- +2.33.0 diff --git a/0089-add-struct-gz-addr.patch b/0089-add-struct-gz-addr.patch index 09729fd..18ffa01 100644 --- a/0089-add-struct-gz-addr.patch +++ b/0089-add-struct-gz-addr.patch @@ -1,7 +1,20 @@ -diff -Nur lwip-org/src/core/tcp.c lwip-gz-addr/src/core/tcp.c ---- lwip-org/src/core/tcp.c 2023-12-04 14:10:25.364481010 +0800 -+++ lwip-gz-addr/src/core/tcp.c 2023-12-04 14:33:31.712481010 +0800 -@@ -1161,7 +1161,7 @@ +From f5df6b241f38a5830920038c05d41ed4444efe63 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 5 Feb 2024 17:41:16 +0800 +Subject: add struct gz addr + +--- + src/core/tcp.c | 2 +- + src/core/udp.c | 2 +- + src/include/lwipopts.h | 1 + + src/include/reg_sock.h | 36 +++++++++++++++++++++++++++++++++--- + 4 files changed, 36 insertions(+), 5 deletions(-) + +diff --git a/src/core/tcp.c b/src/core/tcp.c +index 17f922e..9f240b8 100644 +--- a/src/core/tcp.c ++++ b/src/core/tcp.c +@@ -1161,7 +1161,7 @@ tcp_new_port(void) if (__atomic_load_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], __ATOMIC_ACQUIRE) == 0) { #if GAZELLE_ENABLE @@ -10,10 +23,11 @@ diff -Nur lwip-org/src/core/tcp.c lwip-gz-addr/src/core/tcp.c tmp_port = tcp_port; __atomic_store_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE); break; -diff -Nur lwip-org/src/core/udp.c lwip-gz-addr/src/core/udp.c ---- lwip-org/src/core/udp.c 2023-12-04 14:10:25.364481010 +0800 -+++ lwip-gz-addr/src/core/udp.c 2023-12-04 14:19:58.832481010 +0800 -@@ -132,7 +132,7 @@ +diff --git a/src/core/udp.c b/src/core/udp.c +index 02ffe36..ca82e51 100644 +--- a/src/core/udp.c ++++ b/src/core/udp.c +@@ -132,7 +132,7 @@ udp_new_port(struct udp_pcb *dst_pcb) } if (__atomic_load_n(&port_state[udp_port - UDP_LOCAL_PORT_RANGE_START], __ATOMIC_ACQUIRE) == 0) { @@ -22,10 +36,11 @@ diff -Nur lwip-org/src/core/udp.c lwip-gz-addr/src/core/udp.c tmp_port = udp_port; __atomic_store_n(&port_state[udp_port - UDP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE); break; -diff -Nur lwip-org/src/include/lwipopts.h lwip-gz-addr/src/include/lwipopts.h ---- lwip-org/src/include/lwipopts.h 2023-12-04 14:10:25.368481010 +0800 -+++ lwip-gz-addr/src/include/lwipopts.h 2023-12-06 19:29:24.520481010 +0800 -@@ -184,6 +184,7 @@ +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index 11bc65a..4cd2d7a 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h +@@ -178,6 +178,7 @@ */ #define LWIP_IPV6 1 #define IP6_HLEN 40 @@ -33,9 +48,10 @@ diff -Nur lwip-org/src/include/lwipopts.h lwip-gz-addr/src/include/lwipopts.h /* --------------------------------- -diff -Nur lwip-org/src/include/reg_sock.h lwip-gz-addr/src/include/reg_sock.h ---- lwip-org/src/include/reg_sock.h 2023-12-04 14:10:25.368481010 +0800 -+++ lwip-gz-addr/src/include/reg_sock.h 2023-12-06 19:41:19.792481010 +0800 +diff --git a/src/include/reg_sock.h b/src/include/reg_sock.h +index 5a5e971..a11102e 100644 +--- a/src/include/reg_sock.h ++++ b/src/include/reg_sock.h @@ -34,7 +34,35 @@ #define __REG_SOCK_H__ @@ -73,7 +89,7 @@ diff -Nur lwip-org/src/include/reg_sock.h lwip-gz-addr/src/include/reg_sock.h enum reg_ring_type { REG_RING_TCP_LISTEN = 0, -@@ -45,10 +73,12 @@ +@@ -45,10 +73,12 @@ enum reg_ring_type { }; struct gazelle_quintuple { @@ -87,7 +103,7 @@ diff -Nur lwip-org/src/include/reg_sock.h lwip-gz-addr/src/include/reg_sock.h uint32_t src_ip; uint32_t dst_ip; #if LWIP_IPV6 -@@ -65,6 +95,6 @@ +@@ -65,6 +95,6 @@ struct reg_ring_msg { }; extern int vdev_reg_xmit(enum reg_ring_type type, struct gazelle_quintuple *qtuple); @@ -95,3 +111,6 @@ diff -Nur lwip-org/src/include/reg_sock.h lwip-gz-addr/src/include/reg_sock.h +extern bool port_in_stack_queue(gz_addr_t *src_ip, gz_addr_t *dst_ip, uint16_t src_port, uint16_t dst_port); #endif /* __REG_SOCK_H__ */ +-- +2.33.0 + diff --git a/0091-add-fd-log-info-and-fix-wrong-port-log-info.patch b/0091-add-fd-log-info-and-fix-wrong-port-log-info.patch index a2a8f9d..ccb6fa0 100644 --- a/0091-add-fd-log-info-and-fix-wrong-port-log-info.patch +++ b/0091-add-fd-log-info-and-fix-wrong-port-log-info.patch @@ -9,10 +9,10 @@ Subject: [PATCH] add fd log info and fix wrong port log info 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/api/sockets.c b/src/api/sockets.c -index 65c69d4..d488b5b 100644 +index 7978504..459299a 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c -@@ -2797,7 +2797,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +@@ -2840,7 +2840,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) #endif break; case NETCONN_EVT_ERROR: @@ -22,7 +22,7 @@ index 65c69d4..d488b5b 100644 #if GAZELLE_ENABLE if (netif_is_rtc_mode(netif_default)) { diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 8ed91b5..24706c1 100644 +index 6e84df4..8fb9482 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -688,8 +688,8 @@ aborted: @@ -33,7 +33,7 @@ index 8ed91b5..24706c1 100644 - lwip_ntohs(tcphdr->dest), lwip_ntohs(tcphdr->src))); + ("tcp_input: no PCB match found, send RST, local_port=%d, remote_port=%d\n", + tcphdr->src, tcphdr->dest)); - tcp_rst(NULL, ackno, seqno + tcplen, ip_current_dest_addr(), + tcp_rst_netif(ip_data.current_input_netif, ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); } @@ -765,8 +765,8 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) @@ -44,7 +44,7 @@ index 8ed91b5..24706c1 100644 - lwip_ntohs(tcphdr->dest), lwip_ntohs(tcphdr->src))); + ("tcp_listen_input: ACK in LISTEN, send reset, local_port=%d, remote_port=%d\n", + tcphdr->src, tcphdr->dest)); - tcp_rst((const struct tcp_pcb *)pcb, ackno, seqno + tcplen, ip_current_dest_addr(), + tcp_rst_netif(ip_data.current_input_netif, ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); } else if (flags & TCP_SYN) { @@ -902,8 +902,8 @@ tcp_timewait_input(struct tcp_pcb *pcb) diff --git a/0093-modfiy-accept-null-pointer-when-new-conn-receive-RST-packet-in-listening.patch b/0093-modfiy-accept-null-pointer-when-new-conn-receive-RST-packet-in-listening.patch new file mode 100644 index 0000000..df7ee1c --- /dev/null +++ b/0093-modfiy-accept-null-pointer-when-new-conn-receive-RST-packet-in-listening.patch @@ -0,0 +1,37 @@ +From dcdd7d73c6083a63fe966a68f11eddcafa3fd743 Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Thu, 14 Dec 2023 14:51:37 +0800 +Subject: [PATCH] resove null pointer + +--- + src/api/sockets.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index a9d39ae..0b3e4ea 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -801,15 +801,17 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) + #endif /* GAZELLE_ENABLE */ + nsock = &sockets[newsock - LWIP_SOCKET_OFFSET]; + #if GAZELLE_ENABLE ++ int ret = 0; + struct tcp_pcb *pcb = newconn->pcb.tcp; +- if (pcb->client_rx_ring != NULL && pcb->client_tx_ring != NULL) { +- if (find_same_node_memzone(pcb, nsock) != 0) { ++ if (pcb != NULL && pcb->client_rx_ring != NULL && pcb->client_tx_ring != NULL) { ++ ret = find_same_node_memzone(pcb, nsock); ++ } ++ if (pcb == NULL || ret != 0) { + netconn_delete(newconn); + free_socket(nsock, 1); + sock_set_errno(sock, ENOTCONN); + done_socket(sock); + return -1; +- } + } + #endif + +-- +2.33.0 + diff --git a/0094-lwip-log-fix-reversed-port-in-tcp_input.patch b/0094-lwip-log-fix-reversed-port-in-tcp_input.patch new file mode 100644 index 0000000..c641be6 --- /dev/null +++ b/0094-lwip-log-fix-reversed-port-in-tcp_input.patch @@ -0,0 +1,61 @@ +From ce3debdf4c4cd6701cdb323377477539a5fd13fa Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Fri, 15 Dec 2023 17:21:54 +0800 +Subject: [PATCH] lwip log: fix reversed port in tcp_input + +--- + src/core/tcp_in.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c +index 8fb9482..92ea748 100644 +--- a/src/core/tcp_in.c ++++ b/src/core/tcp_in.c +@@ -689,7 +689,7 @@ aborted: + TCP_STATS_INC(tcp.drop); + LWIP_DEBUGF(TCP_RST_DEBUG | GAZELLE_DEBUG_SERIOUS, + ("tcp_input: no PCB match found, send RST, local_port=%d, remote_port=%d\n", +- tcphdr->src, tcphdr->dest)); ++ tcphdr->dest, tcphdr->src)); + tcp_rst_netif(ip_data.current_input_netif, ackno, seqno + tcplen, ip_current_dest_addr(), + ip_current_src_addr(), tcphdr->dest, tcphdr->src); + } +@@ -766,7 +766,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) + RST. */ + LWIP_DEBUGF(TCP_RST_DEBUG | GAZELLE_DEBUG_SERIOUS, + ("tcp_listen_input: ACK in LISTEN, send reset, local_port=%d, remote_port=%d\n", +- tcphdr->src, tcphdr->dest)); ++ tcphdr->dest, tcphdr->src)); + tcp_rst_netif(ip_data.current_input_netif, ackno, seqno + tcplen, ip_current_dest_addr(), + ip_current_src_addr(), tcphdr->dest, tcphdr->src); + } else if (flags & TCP_SYN) { +@@ -903,7 +903,7 @@ tcp_timewait_input(struct tcp_pcb *pcb) + /* If the SYN is in the window it is an error, send a reset */ + LWIP_DEBUGF(GAZELLE_DEBUG_SERIOUS, + ("tcp_timewait_input: SYN in TIME_WAIT, send RST, local_port=%d, remote_port=%d\n", +- tcphdr->src, tcphdr->dest)); ++ tcphdr->dest, tcphdr->src)); + tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(), + ip_current_src_addr(), tcphdr->dest, tcphdr->src); + return; +@@ -1073,7 +1073,7 @@ tcp_process(struct tcp_pcb *pcb) + else if (flags & TCP_ACK) { + /* send a RST to bring the other side in a non-synchronized state. */ + LWIP_DEBUGF(GAZELLE_DEBUG_SERIOUS, ("tcp_process: ACK in SYN_SENT, send RST, local_port=%d, remote_port=%d\n", +- tcphdr->src, tcphdr->dest)); ++ tcphdr->dest, tcphdr->src)); + tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(), + ip_current_src_addr(), tcphdr->dest, tcphdr->src); + /* Resend SYN immediately (don't wait for rto timeout) to establish +@@ -1146,7 +1146,7 @@ tcp_process(struct tcp_pcb *pcb) + /* incorrect ACK number, send RST */ + LWIP_DEBUGF(GAZELLE_DEBUG_SERIOUS, + ("tcp_process: incorrect ACK number in SYN_RCVD, send RST, ackno=%d, lastack=%d, snd_nxt=%d, local_port=%d, remote_port=%d\n", +- ackno, pcb->lastack, pcb->snd_nxt, tcphdr->src, tcphdr->dest)); ++ ackno, pcb->lastack, pcb->snd_nxt, tcphdr->dest, tcphdr->src)); + tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(), + ip_current_src_addr(), tcphdr->dest, tcphdr->src); + } +-- +2.33.0 + diff --git a/0095-event_callback-del-errevent-log-if-err-is-ERR_OK.patch b/0095-event_callback-del-errevent-log-if-err-is-ERR_OK.patch new file mode 100644 index 0000000..9260abc --- /dev/null +++ b/0095-event_callback-del-errevent-log-if-err-is-ERR_OK.patch @@ -0,0 +1,27 @@ +From db1929c5698a672200bf96d7ece992f10a98a80c Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Wed, 20 Dec 2023 17:37:42 +0800 +Subject: [PATCH] event_callback: del errevent log if err is ERR_OK + +--- + src/api/sockets.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index 0b3e4ea..f5b8ea6 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -2805,7 +2805,9 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) + #endif + break; + case NETCONN_EVT_ERROR: +- LWIP_DEBUGF(GAZELLE_DEBUG_SERIOUS, ("event_callback: have errevent, err=%d, fd=%d\n", conn->pending_err, conn->socket)); ++ if (conn->pending_err != ERR_OK) { ++ LWIP_DEBUGF(GAZELLE_DEBUG_SERIOUS, ("event_callback: have errevent, err=%d, fd=%d\n", conn->pending_err, conn->socket)); ++ } + sock->errevent = 1; + #if GAZELLE_ENABLE + if (netif_is_rtc_mode(netif_default)) { +-- +2.33.0 + diff --git a/0096-tcp_send_fin-add-the-fin-to-the-last-unsent-segment.patch b/0096-tcp_send_fin-add-the-fin-to-the-last-unsent-segment.patch new file mode 100644 index 0000000..2e77f0e --- /dev/null +++ b/0096-tcp_send_fin-add-the-fin-to-the-last-unsent-segment.patch @@ -0,0 +1,27 @@ +From c91f1d05c65526fe250cf5e5c32f9038721bc1d5 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Mon, 25 Dec 2023 12:39:56 +0800 +Subject: [PATCH] tcp_send_fin: add the fin to the last unsent segment + +--- + src/core/tcp_out.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c +index 137e3cf..e5c407e 100644 +--- a/src/core/tcp_out.c ++++ b/src/core/tcp_out.c +@@ -1195,8 +1195,8 @@ tcp_send_fin(struct tcp_pcb *pcb) + LWIP_ASSERT("tcp_send_fin: invalid pcb", pcb != NULL); + + /* first, try to add the fin to the last unsent segment */ +- if (pcb->unsent != NULL) { +- struct tcp_seg *last_unsent = pcb->unsent; ++ if (pcb->last_unsent != NULL) { ++ struct tcp_seg *last_unsent = pcb->last_unsent; + + if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) { + /* no SYN/FIN/RST flag in the header, we can add the FIN flag */ +-- +2.33.0 + diff --git a/0097-Mod-the-issue-that-2w-connection-unable-to-establish.patch b/0097-Mod-the-issue-that-2w-connection-unable-to-establish.patch new file mode 100644 index 0000000..9b53997 --- /dev/null +++ b/0097-Mod-the-issue-that-2w-connection-unable-to-establish.patch @@ -0,0 +1,275 @@ +From 212198780662639e0422419a25d28ff2bb0d421e Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Mon, 25 Dec 2023 15:36:45 +0800 +Subject: [PATCH] Mod the issue that 2w connection unable to establish in + Redis. + +--- + src/api/api_lib.c | 2 +- + src/api/api_msg.c | 2 +- + src/api/sockets.c | 19 ++++++++++++------- + src/core/init.c | 4 ++-- + src/core/tcp.c | 4 ++-- + src/core/tcp_in.c | 2 +- + src/include/lwip/api.h | 2 +- + src/include/lwip/opt.h | 2 +- + src/include/lwip/priv/api_msg.h | 2 +- + src/include/lwip/tcp.h | 8 ++++---- + src/include/lwipopts.h | 4 ++-- + 11 files changed, 28 insertions(+), 23 deletions(-) + +diff --git a/src/api/api_lib.c b/src/api/api_lib.c +index b22b987..1721d49 100644 +--- a/src/api/api_lib.c ++++ b/src/api/api_lib.c +@@ -431,7 +431,7 @@ netconn_disconnect(struct netconn *conn) + * don't return any error (yet?)) + */ + err_t +-netconn_listen_with_backlog(struct netconn *conn, u8_t backlog) ++netconn_listen_with_backlog(struct netconn *conn, u16_t backlog) + { + #if LWIP_TCP + API_MSG_VAR_DECLARE(msg); +diff --git a/src/api/api_msg.c b/src/api/api_msg.c +index 3fda788..b06be0a 100644 +--- a/src/api/api_msg.c ++++ b/src/api/api_msg.c +@@ -1500,7 +1500,7 @@ lwip_netconn_do_listen(void *m) + /* connection is not closed, cannot listen */ + err = ERR_VAL; + } else { +- u8_t backlog; ++ u16_t backlog; + #if TCP_LISTEN_BACKLOG + backlog = msg->msg.lb.backlog; + #else /* TCP_LISTEN_BACKLOG */ +diff --git a/src/api/sockets.c b/src/api/sockets.c +index d1e1615..ced0c37 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -487,7 +487,7 @@ tryget_socket_unconn_nouse(int fd) + if ((s < 0) || (s >= NUM_SOCKETS)) + #endif /* GAZELLE_ENABLE */ + { +- LWIP_DEBUGF(SOCKETS_DEBUG, ("tryget_socket_unconn(%d): invalid\n", fd)); ++ LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("tryget_socket_unconn(%d): invalid\n", fd)); + return NULL; + } + return &sockets[s]; +@@ -561,7 +561,7 @@ get_socket(int fd) + struct lwip_sock *sock = tryget_socket(fd); + if (!sock) { + if ((fd < LWIP_SOCKET_OFFSET) || (fd >= (LWIP_SOCKET_OFFSET + NUM_SOCKETS))) { +- LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", fd)); ++ LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("get_socket(%d): invalid\n", fd)); + } + set_errno(EBADF); + return NULL; +@@ -628,6 +628,7 @@ alloc_socket(struct netconn *newconn, int accepted, int flags) + SYS_ARCH_PROTECT(lev); + i = posix_api->socket_fn(domain, type, protocol); + if (i == -1) { ++ LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("posix_api->socket_fn fail socket is -1")); + goto err; + } + +@@ -636,6 +637,7 @@ alloc_socket(struct netconn *newconn, int accepted, int flags) + } + + if ((i < LWIP_SOCKET_OFFSET) || (i >= sockets_num + LWIP_SOCKET_OFFSET)) { ++ LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("posix_api->socket_fn socket is %d, illegal\n", i)); + goto err; + } + +@@ -806,13 +808,14 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); + sock = get_socket(s); + if (!sock) { ++ LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("get_socket sock is null\n")); + return -1; + } + + /* wait for a new connection */ + err = netconn_accept(sock->conn, &newconn); + if (err != ERR_OK) { +- LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); ++ LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + set_errno(EOPNOTSUPP); + } else if (err == ERR_CLSD) { +@@ -827,6 +830,7 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) + + newsock = alloc_socket(newconn, 1, flags); + if (newsock == -1) { ++ LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("alloc_socket fail newsock is -1\n")); + netconn_delete(newconn); + set_errno(ENFILE); + done_socket(sock); +@@ -846,6 +850,7 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) + ret = find_same_node_memzone(pcb, nsock); + } + if (pcb == NULL || ret != 0) { ++ LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("alloc_socket fail pcb null flag=%u, ret=%d \n", (pcb == NULL), ret)); + netconn_delete(newconn); + free_socket(nsock, 1); + sock_set_errno(sock, ENOTCONN); +@@ -881,7 +886,7 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) + /* get the IP address and port of the remote host */ + err = netconn_peer(newconn, &naddr, &port); + if (err != ERR_OK) { +- LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); ++ LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); + free_socket(nsock, 1); + set_errno(err_to_errno(err)); + done_socket(sock); +@@ -1096,10 +1101,10 @@ lwip_listen(int s, int backlog) + return -1; + } + +- /* limit the "backlog" parameter to fit in an u8_t */ +- backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); ++ /* limit the "backlog" parameter to fit in an u16_t */ ++ backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xffff); + +- err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog); ++ err = netconn_listen_with_backlog(sock->conn, (u16_t)backlog); + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); +diff --git a/src/core/init.c b/src/core/init.c +index 36d7093..c0aaf45 100644 +--- a/src/core/init.c ++++ b/src/core/init.c +@@ -160,8 +160,8 @@ PACK_STRUCT_END + #if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12))) + #error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h" + #endif +-#if (LWIP_TCP && TCP_LISTEN_BACKLOG && ((TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff))) +-#error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t" ++#if (LWIP_TCP && TCP_LISTEN_BACKLOG && ((TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xffff))) ++#error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u16_t" + #endif + #if (LWIP_TCP && LWIP_TCP_SACK_OUT && !TCP_QUEUE_OOSEQ) + #error "To use LWIP_TCP_SACK_OUT, TCP_QUEUE_OOSEQ needs to be enabled" +diff --git a/src/core/tcp.c b/src/core/tcp.c +index 9f240b8..a9a6513 100644 +--- a/src/core/tcp.c ++++ b/src/core/tcp.c +@@ -903,7 +903,7 @@ tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err) + * tpcb = tcp_listen_with_backlog(tpcb, backlog); + */ + struct tcp_pcb * +-tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) ++tcp_listen_with_backlog(struct tcp_pcb *pcb, u16_t backlog) + { + LWIP_ASSERT_CORE_LOCKED(); + return tcp_listen_with_backlog_and_err(pcb, backlog, NULL); +@@ -926,7 +926,7 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) + * tpcb = tcp_listen_with_backlog_and_err(tpcb, backlog, &err); + */ + struct tcp_pcb * +-tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) ++tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u16_t backlog, err_t *err) + { + struct tcp_pcb_listen *lpcb = NULL; + err_t res; +diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c +index 92ea748..5e081f9 100644 +--- a/src/core/tcp_in.c ++++ b/src/core/tcp_in.c +@@ -785,7 +785,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) + SYN at a time when we have more memory available. */ + if (npcb == NULL) { + err_t err; +- LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); ++ LWIP_DEBUGF(TCP_DEBUG | GAZELLE_DEBUG_SERIOUS, ("tcp_listen_input: could not allocate PCB\n")); + TCP_STATS_INC(tcp.memerr); + TCP_EVENT_ACCEPT(pcb, NULL, pcb->callback_arg, ERR_MEM, err); + LWIP_UNUSED_ARG(err); /* err not useful here */ +diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h +index 6e6e52d..5d03c24 100644 +--- a/src/include/lwip/api.h ++++ b/src/include/lwip/api.h +@@ -366,7 +366,7 @@ err_t netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port); + err_t netconn_bind_if(struct netconn *conn, u8_t if_idx); + err_t netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port); + err_t netconn_disconnect (struct netconn *conn); +-err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog); ++err_t netconn_listen_with_backlog(struct netconn *conn, u16_t backlog); + /** @ingroup netconn_tcp */ + #define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG) + err_t netconn_accept(struct netconn *conn, struct netconn **new_conn); +diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h +index e61b3f1..53b1946 100644 +--- a/src/include/lwip/opt.h ++++ b/src/include/lwip/opt.h +@@ -1467,7 +1467,7 @@ + * 0xff is the maximum (u8_t). + */ + #if !defined TCP_DEFAULT_LISTEN_BACKLOG || defined __DOXYGEN__ +-#define TCP_DEFAULT_LISTEN_BACKLOG 0xff ++#define TCP_DEFAULT_LISTEN_BACKLOG 0xffff + #endif + + /** +diff --git a/src/include/lwip/priv/api_msg.h b/src/include/lwip/priv/api_msg.h +index 9e8ffc9..b36f00a 100644 +--- a/src/include/lwip/priv/api_msg.h ++++ b/src/include/lwip/priv/api_msg.h +@@ -145,7 +145,7 @@ struct api_msg { + #endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ + #if TCP_LISTEN_BACKLOG + struct { +- u8_t backlog; ++ u16_t backlog; + } lb; + #endif /* TCP_LISTEN_BACKLOG */ + } msg; +diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h +index bde17ec..5097179 100644 +--- a/src/include/lwip/tcp.h ++++ b/src/include/lwip/tcp.h +@@ -249,8 +249,8 @@ struct tcp_pcb_listen { + #endif /* LWIP_CALLBACK_API */ + + #if TCP_LISTEN_BACKLOG +- u8_t backlog; +- u8_t accepts_pending; ++ u16_t backlog; ++ u16_t accepts_pending; + #endif /* TCP_LISTEN_BACKLOG */ + + #if GAZELLE_TCP_REUSE_IPPORT +@@ -574,8 +574,8 @@ void tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif); + err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, + u16_t port, tcp_connected_fn connected); + +-struct tcp_pcb * tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err); +-struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); ++struct tcp_pcb * tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u16_t backlog, err_t *err); ++struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u16_t backlog); + /** @ingroup tcp_raw */ + #define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) + +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index 4cd2d7a..d54ff1e 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h +@@ -203,11 +203,11 @@ + + #define TCP_HLEN 20 + +-#define DEFAULT_ACCEPTMBOX_SIZE 1024 ++#define DEFAULT_ACCEPTMBOX_SIZE 4096 + #define DEFAULT_TCP_RECVMBOX_SIZE 4096 + + #define TCP_LISTEN_BACKLOG 1 +-#define TCP_DEFAULT_LISTEN_BACKLOG 0xff ++#define TCP_DEFAULT_LISTEN_BACKLOG 0xffff + + #define TCP_OVERSIZE TCP_MSS + #define LWIP_NETIF_TX_SINGLE_PBUF 1 +-- +2.33.0 + diff --git a/0098-remove-duplicate-lwip-log.patch b/0098-remove-duplicate-lwip-log.patch new file mode 100644 index 0000000..238c202 --- /dev/null +++ b/0098-remove-duplicate-lwip-log.patch @@ -0,0 +1,25 @@ +From 2d01f8467027e5a640ee6c7ed72d64d8e0247829 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Wed, 27 Dec 2023 10:40:54 +0800 +Subject: [PATCH] remove duplicate log + +--- + src/core/tcp_in.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c +index 5e081f9..118210a 100644 +--- a/src/core/tcp_in.c ++++ b/src/core/tcp_in.c +@@ -764,7 +764,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) + if (flags & TCP_ACK) { + /* For incoming segments with the ACK flag set, respond with a + RST. */ +- LWIP_DEBUGF(TCP_RST_DEBUG | GAZELLE_DEBUG_SERIOUS, ++ LWIP_DEBUGF(TCP_RST_DEBUG, + ("tcp_listen_input: ACK in LISTEN, send reset, local_port=%d, remote_port=%d\n", + tcphdr->dest, tcphdr->src)); + tcp_rst_netif(ip_data.current_input_netif, ackno, seqno + tcplen, ip_current_dest_addr(), +-- +2.27.0 + diff --git a/0099-fix-rte_ring_create-time-consuming.patch b/0099-fix-rte_ring_create-time-consuming.patch new file mode 100644 index 0000000..1c7d174 --- /dev/null +++ b/0099-fix-rte_ring_create-time-consuming.patch @@ -0,0 +1,142 @@ +From 01be1587c5e6771da95d6cf8d387c0b5ba15c275 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Wed, 27 Dec 2023 10:19:34 +0800 +Subject: [PATCH] fix rte_ring_create time consuming + +--- + src/api/sockets.c | 2 +- + src/api/sys_arch.c | 63 ++++++++++++++++++++++++++++--------- + src/include/arch/sys_arch.h | 4 +++ + 3 files changed, 54 insertions(+), 15 deletions(-) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index 0cff4c4..d4cae53 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -2844,7 +2844,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) + #endif + break; + case NETCONN_EVT_ERROR: +- if (conn->pending_err != ERR_OK) { ++ if ((conn->pending_err != ERR_OK) && (conn->pending_err != ERR_RST)) { + LWIP_DEBUGF(GAZELLE_DEBUG_SERIOUS, ("event_callback: have errevent, err=%d, fd=%d\n", conn->pending_err, conn->socket)); + } + sock->errevent = 1; +diff --git a/src/api/sys_arch.c b/src/api/sys_arch.c +index 1bc3aee..b80c0a8 100644 +--- a/src/api/sys_arch.c ++++ b/src/api/sys_arch.c +@@ -37,6 +37,7 @@ + #include + + #include ++#include + + #include "lwip/err.h" + #include "lwip/mem.h" +@@ -89,9 +90,50 @@ static int mbox_wait_func(void) + return eth_dev_poll(); + } + ++struct rte_ring *gazelle_ring_create_fast(const char *name, uint32_t size, uint32_t flags) ++{ ++ ssize_t ring_size; ++ char ring_name[RTE_MEMZONE_NAMESIZE] = {0}; ++ struct rte_ring *ring; ++ ++ ring_size = rte_ring_get_memsize(size); ++ if (ring_size < 0) { ++ RTE_LOG(ERR, EAL, "rte_ring_get_memszie failed\n"); ++ return NULL; ++ } ++ ++ /* ++ * rte_ring_create is not used because it calls memzone_lookup_thread_unsafe function ++ * time consuming when there are many rings ++ */ ++ ring = rte_malloc_socket(NULL, ring_size, RTE_CACHE_LINE_SIZE, rte_socket_id()); ++ if (ring == NULL) { ++ RTE_LOG(ERR, EAL, "cannot create rte_ring for mbox\n"); ++ return NULL; ++ } ++ ++ if (snprintf(ring_name, sizeof(ring_name), "%s""%"PRIXPTR, name, (uintptr_t)ring) < 0) { ++ rte_free(ring); ++ RTE_LOG(ERR, EAL, "snprintf failed\n"); ++ return NULL; ++ } ++ ++ if (rte_ring_init(ring, ring_name, size, flags) != 0) { ++ rte_free(ring); ++ RTE_LOG(ERR, EAL, "cannot init rte_ring for mbox\n"); ++ return NULL; ++ } ++ ++ return ring; ++} ++ ++void gazelle_ring_free_fast(struct rte_ring *ring) ++{ ++ rte_free(ring); ++} ++ + err_t sys_mbox_new(struct sys_mbox **mb, int size) + { +- int ret; + struct sys_mbox *mbox; + + mbox = (struct sys_mbox *)memp_malloc(MEMP_SYS_MBOX); +@@ -100,21 +142,15 @@ err_t sys_mbox_new(struct sys_mbox **mb, int size) + } + + mbox->flags = RING_F_SP_ENQ | RING_F_SC_DEQ; +- +- ret = snprintf(mbox->name, sizeof(mbox->name), MBOX_NAME_PREFIX"%"PRIXPTR, (uintptr_t)mbox); +- if (ret < 0) { +- memp_free(MEMP_SYS_MBOX, mbox); +- return ERR_VAL; +- } +- + mbox->size = size; + mbox->socket_id = rte_socket_id(); +- mbox->ring = rte_ring_create(mbox->name, mbox->size, mbox->socket_id, mbox->flags); +- if (!mbox->ring) { +- RTE_LOG(ERR, EAL, "cannot create rte_ring for mbox\n"); +- memp_free(MEMP_SYS_MBOX, mbox); ++ ++ mbox->ring = gazelle_ring_create_fast(MBOX_NAME_PREFIX, mbox->size, mbox->flags); ++ if (mbox->ring == NULL) { ++ sys_mbox_free(&mbox); + return ERR_MEM; + } ++ + mbox->wait_fn = mbox_wait_func; + *mb = mbox; + +@@ -125,7 +161,7 @@ void sys_mbox_free(struct sys_mbox **mb) + { + struct sys_mbox *mbox = *mb; + if (mbox->ring != NULL) { +- rte_ring_free(mbox->ring); ++ gazelle_ring_free_fast(mbox->ring); + mbox->ring = NULL; + } + memp_free(MEMP_SYS_MBOX, mbox); +diff --git a/src/include/arch/sys_arch.h b/src/include/arch/sys_arch.h +index 5e95f3d..bf7e437 100644 +--- a/src/include/arch/sys_arch.h ++++ b/src/include/arch/sys_arch.h +@@ -123,6 +123,10 @@ static __rte_always_inline uint32_t gazelle_st_ring_dequeue_burst(struct rte_rin + + return n; + } ++ ++void gazelle_ring_free_fast(struct rte_ring *ring); ++struct rte_ring *gazelle_ring_create_fast(const char *name, uint32_t size, uint32_t flags); ++ + #endif + + void sys_calibrate_tsc(void); +-- +2.33.0 + diff --git a/0100-replace-qtuple-addr-with-gz_addr_t.patch b/0100-replace-qtuple-addr-with-gz_addr_t.patch new file mode 100644 index 0000000..aa481e2 --- /dev/null +++ b/0100-replace-qtuple-addr-with-gz_addr_t.patch @@ -0,0 +1,85 @@ +From 430469b1fa14ed689781eeed14dc8ce7cadd22a3 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 5 Feb 2024 19:16:07 +0800 +Subject: replace qtuple addr with gz_addr_t + +--- + src/include/lwip/priv/tcp_priv.h | 24 ++++++------------------ + src/include/reg_sock.h | 19 ++++++++++++------- + 2 files changed, 18 insertions(+), 25 deletions(-) + +diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h +index 75c67ee..8d7b9df 100644 +--- a/src/include/lwip/priv/tcp_priv.h ++++ b/src/include/lwip/priv/tcp_priv.h +@@ -347,24 +347,12 @@ static inline int vdev_reg_done(enum reg_ring_type reg_type, const struct tcp_pc + LWIP_ASSERT("Invalid parameter", pcb != NULL); + + struct gazelle_quintuple qtuple; +- if (IP_IS_V4_VAL(pcb->local_ip)) { +- qtuple.protocol = 0; +- qtuple.src_ip = ip_2_ip4(&pcb->local_ip)->addr; +- qtuple.src_port = lwip_htons(pcb->local_port); +- qtuple.dst_ip = ip_2_ip4(&pcb->remote_ip)->addr; +- qtuple.dst_port = lwip_htons(pcb->remote_port); +- } else { +-#if LWIP_IPV6 +- qtuple.protocol = 1; +- qtuple.src_port = lwip_htons(pcb->local_port); +- qtuple.dst_port = lwip_htons(pcb->remote_port); +- +- for (int i = 0; i < 4; i++) { +- qtuple.src_ip6[i] = pcb->local_ip.u_addr.ip6.addr[i]; +- qtuple.dst_ip6[i] = pcb->remote_ip.u_addr.ip6.addr[i]; +- } +-#endif +- } ++ ++ qtuple.protocol = IP_IS_V4_VAL(pcb->local_ip) ? GZ_ADDR_TYPE_V4 : GZ_ADDR_TYPE_V6; ++ qtuple.src_ip = *((gz_addr_t *)&pcb->local_ip); ++ qtuple.src_port = lwip_htons(pcb->local_port); ++ qtuple.dst_ip = *((gz_addr_t *)&pcb->remote_ip); ++ qtuple.dst_port = lwip_htons(pcb->remote_port); + + #if GAZELLE_TCP_REUSE_IPPORT + if (reg_type == REG_RING_TCP_CONNECT_CLOSE) { +diff --git a/src/include/reg_sock.h b/src/include/reg_sock.h +index a11102e..466a2c2 100644 +--- a/src/include/reg_sock.h ++++ b/src/include/reg_sock.h +@@ -37,6 +37,16 @@ + + #include "lwipopts.h" + ++/* compatible with lwip_ip_addr_type */ ++enum gz_ip_addr_type { ++ /** IPv4 */ ++ GZ_ADDR_TYPE_V4 = 0U, ++ /** IPv6 */ ++ GZ_ADDR_TYPE_V6 = 6U, ++ /** IPv4+IPv6 ("dual-stack") */ ++ GZ_ADDR_TYPE_ANY = 46U ++}; ++ + /* compatible with ip4_addr_t */ + struct gz_ip4 { + uint32_t addr; +@@ -78,13 +88,8 @@ struct gazelle_quintuple { + uint16_t src_port; + uint16_t dst_port; + +- /* TODO: replace with gz_addr_t */ +- uint32_t src_ip; +- uint32_t dst_ip; +-#if LWIP_IPV6 +- uint32_t src_ip6[4]; +- uint32_t dst_ip6[4]; +-#endif ++ gz_addr_t src_ip; ++ gz_addr_t dst_ip; + }; + + struct reg_ring_msg { +-- +2.33.0 + diff --git a/0101-fix-wrong-namelen-in-getaddrname.patch b/0101-fix-wrong-namelen-in-getaddrname.patch new file mode 100644 index 0000000..cced77c --- /dev/null +++ b/0101-fix-wrong-namelen-in-getaddrname.patch @@ -0,0 +1,26 @@ +From d926ce84920e03b150c60d842f8cd4c4cea671f5 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 5 Feb 2024 19:16:37 +0800 +Subject: fix wrong namelen in getaddrname + +--- + src/api/sockets.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index f3b8f8c..250c424 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -3063,7 +3063,8 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) + *namelen = IPADDR_SOCKADDR_GET_LEN(&saddr); + } + #else +- *namelen = LWIP_MIN(*namelen, sizeof(saddr)); ++ u8_t sa_len = IP_IS_V4_VAL(naddr) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); ++ *namelen = LWIP_MIN(*namelen, sa_len); + #endif + MEMCPY(name, &saddr, *namelen); + +-- +2.33.0 + diff --git a/0102-dfx-add-tcp_in-empty-ack-cnt-and-del-rst-invalid-log.patch b/0102-dfx-add-tcp_in-empty-ack-cnt-and-del-rst-invalid-log.patch new file mode 100644 index 0000000..d296965 --- /dev/null +++ b/0102-dfx-add-tcp_in-empty-ack-cnt-and-del-rst-invalid-log.patch @@ -0,0 +1,76 @@ +From 105f7e2a5828d1999bdbf0bb64d336f22dc67859 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Mon, 8 Jan 2024 15:22:09 +0800 +Subject: [PATCH] dfx: add tcp_in empty ack cnt and del rst invalid log + +--- + src/core/tcp_in.c | 8 ++++++-- + src/include/lwip/stats.h | 1 + + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c +index 118210a..d6f54b6 100644 +--- a/src/core/tcp_in.c ++++ b/src/core/tcp_in.c +@@ -523,6 +523,7 @@ tcp_input(struct pbuf *p, struct netif *inp) + if (pcb->rcv_ann_wnd == 0) { + /* this is a zero-window probe, we respond to it with current RCV.NXT + and drop the data segment */ ++ MIB2_STATS_INC(mib2.tcpinemptyacks); + tcp_send_empty_ack(pcb); + } + TCP_STATS_INC(tcp.drop); +@@ -687,8 +688,7 @@ aborted: + if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { + TCP_STATS_INC(tcp.proterr); + TCP_STATS_INC(tcp.drop); +- LWIP_DEBUGF(TCP_RST_DEBUG | GAZELLE_DEBUG_SERIOUS, +- ("tcp_input: no PCB match found, send RST, local_port=%d, remote_port=%d\n", ++ LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, send RST, local_port=%d, remote_port=%d\n", + tcphdr->dest, tcphdr->src)); + tcp_rst_netif(ip_data.current_input_netif, ackno, seqno + tcplen, ip_current_dest_addr(), + ip_current_src_addr(), tcphdr->dest, tcphdr->src); +@@ -1517,6 +1517,7 @@ tcp_receive(struct tcp_pcb *pcb) + /* End of ACK for new data processing. */ + } else { + /* Out of sequence ACK, didn't really ack anything */ ++ MIB2_STATS_INC(mib2.tcpinemptyacks); + tcp_send_empty_ack(pcb); + } + +@@ -1818,6 +1819,7 @@ tcp_receive(struct tcp_pcb *pcb) + but lwIP currently does not support including SACKs in data packets. So we force + it to respond with an empty ACK packet (only if there is at least one SACK to be sent). + NOTE: tcp_send_empty_ack() on success clears the ACK flags (set by tcp_ack()) */ ++ MIB2_STATS_INC(mib2.tcpinemptyacks); + tcp_send_empty_ack(pcb); + } + #endif /* LWIP_TCP_SACK_OUT */ +@@ -2058,10 +2060,12 @@ tcp_receive(struct tcp_pcb *pcb) + + /* We send the ACK packet after we've (potentially) dealt with SACKs, + so they can be included in the acknowledgment. */ ++ MIB2_STATS_INC(mib2.tcpinemptyacks); + tcp_send_empty_ack(pcb); + } + } else { + /* The incoming segment is not within the window. */ ++ MIB2_STATS_INC(mib2.tcpinemptyacks); + tcp_send_empty_ack(pcb); + } + } else { +diff --git a/src/include/lwip/stats.h b/src/include/lwip/stats.h +index 805836c..08c34e9 100644 +--- a/src/include/lwip/stats.h ++++ b/src/include/lwip/stats.h +@@ -156,6 +156,7 @@ struct stats_mib2 { + u32_t tcpoutofseq; + u32_t tcpacceptmboxfull; + u32_t tcplistendrops; ++ u32_t tcpinemptyacks; + + /* UDP */ + u32_t udpindatagrams; +-- +2.33.0 + diff --git a/0103-adapt-for-dpdk-23.11.patch b/0103-adapt-for-dpdk-23.11.patch new file mode 100644 index 0000000..6c0e84e --- /dev/null +++ b/0103-adapt-for-dpdk-23.11.patch @@ -0,0 +1,280 @@ +From 055e167029e3cee7ee8db8f8692efaec0300f374 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Sat, 13 Jan 2024 20:52:37 +0800 +Subject: [PATCH] adapt for dpdk-23.11 + +--- + src/Makefile | 3 --- + src/core/ipv4/icmp.c | 2 +- + src/core/ipv4/ip4.c | 6 ++--- + src/core/ipv4/ip4_frag.c | 4 ++-- + src/core/ipv6/ip6.c | 2 +- + src/core/tcp_in.c | 2 +- + src/core/tcp_out.c | 6 ++--- + src/core/udp.c | 4 ++-- + src/include/dpdk_version.h | 46 ++++++++++++++++++++++++++++---------- + src/netif/ethernet.c | 4 ++-- + 10 files changed, 49 insertions(+), 30 deletions(-) + +diff --git a/src/Makefile b/src/Makefile +index 480470f..ce059e1 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -2,7 +2,12 @@ LWIP_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + ROOT_DIR := $(dir $(abspath $(LWIP_DIR))) + + LWIP_INC = $(LWIP_DIR)/include +-DPDK_INCLUDE_FILE ?= /usr/include/dpdk ++DPDK_VERSION := $(shell rpm -q --queryformat '%{VERSION}' dpdk) ++ifeq ($(DPDK_VERSION),21.11) ++ DPDK_INCLUDE_FILE := /usr/local/include ++else ++ DPDK_INCLUDE_FILE := /usr/include/dpdk ++endif + + SEC_FLAGS = -fstack-protector-strong -Werror -Wall -Wl,-z,relro,-z,now -Wl,-z,noexecstack -Wtrampolines -fPIC -D_FORTIRY_SOURCE=2 -O2 + +@@ -19,9 +24,6 @@ ARFLAGS = crDP + ifeq ($(shell $(CC) -dumpmachine | cut -d"-" -f1), x86_64) + CFLAGS += -mssse3 + endif +-ifeq ($(DPDK_VERSION_1911), 1) +- CFLAGS += -DDPDK_VERSION_1911=1 +-endif + + SRCS = + DIRS = api core netif +diff --git a/src/core/ipv4/icmp.c b/src/core/ipv4/icmp.c +index 2984d24..a3de92d 100644 +--- a/src/core/ipv4/icmp.c ++++ b/src/core/ipv4/icmp.c +@@ -241,7 +241,7 @@ icmp_input(struct pbuf *p, struct netif *inp) + #if CHECKSUM_GEN_IP + IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) { + #if CHECKSUM_GEN_IP_HW +- if (netif_get_txol_flags(inp) & DEV_TX_OFFLOAD_IPV4_CKSUM) { ++ if (netif_get_txol_flags(inp) & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) { + iph_cksum_set(p, hlen, 1); + } else { + iph_cksum_set(p, hlen, 0); +diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c +index 4335423..907a2f0 100644 +--- a/src/core/ipv4/ip4.c ++++ b/src/core/ipv4/ip4.c +@@ -543,7 +543,7 @@ ip4_input(struct pbuf *p, struct netif *inp) + IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) { + #if CHECKSUM_CHECK_IP_HW + u64_t ret; +- if (netif_get_rxol_flags(inp) & DEV_RX_OFFLOAD_IPV4_CKSUM) { ++ if (netif_get_rxol_flags(inp) & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) { + ret = is_cksum_ipbad(p); + } else { + ret = (u64_t)inet_chksum(iphdr, iphdr_hlen); +@@ -1020,7 +1020,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d + #if CHECKSUM_GEN_IP + IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { + #if CHECKSUM_GEN_IP_HW +- if (netif_get_txol_flags(netif) & DEV_TX_OFFLOAD_IPV4_CKSUM) { ++ if (netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) { + iph_cksum_set(p, ip_hlen, 1); + } else { + iph_cksum_set(p, ip_hlen, 0); +@@ -1069,7 +1069,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d + #if IP_FRAG + /* don't fragment if interface has mtu set to 0 [loopif] */ + #if GAZELLE_ENABLE +- if (!(netif_get_txol_flags(netif) & DEV_TX_OFFLOAD_TCP_TSO)) { ++ if (!(netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_TCP_TSO)) { + #endif + if (netif->mtu && (p->tot_len > netif->mtu)) { + return ip4_frag(p, netif, dest); +diff --git a/src/core/ipv4/ip4_frag.c b/src/core/ipv4/ip4_frag.c +index 01e3d60..d9bf5cc 100644 +--- a/src/core/ipv4/ip4_frag.c ++++ b/src/core/ipv4/ip4_frag.c +@@ -642,7 +642,7 @@ ip4_reass(struct pbuf *p) + #if CHECKSUM_GEN_IP + IF__NETIF_CHECKSUM_ENABLED(netif_default, NETIF_CHECKSUM_GEN_IP) { + #if CHECKSUM_GEN_IP_HW +- if (netif_get_txol_flags(netif_default) & DEV_TX_OFFLOAD_IPV4_CKSUM) { ++ if (netif_get_txol_flags(netif_default) & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) { + iph_cksum_set(p, IP_HLEN, 1); + } else { + iph_cksum_set(p, IP_HLEN, 0); +@@ -885,7 +885,7 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest) + #if CHECKSUM_GEN_IP + IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { + #if CHECKSUM_GEN_IP_HW +- if (netif_get_txol_flags(netif) & DEV_TX_OFFLOAD_IPV4_CKSUM) { ++ if (netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) { + iph_cksum_set(p, IP_HLEN, 1); + } else { + iph_cksum_set(p, IP_HLEN, 0); +diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c +index 5f16cd0..9017d87 100644 +--- a/src/core/ipv6/ip6.c ++++ b/src/core/ipv6/ip6.c +@@ -1279,7 +1279,7 @@ ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, + #if LWIP_IPV6_FRAG + /* don't fragment if interface has mtu set to 0 [loopif] */ + #if GAZELLE_ENABLE +- if (!(netif_get_txol_flags(netif) & DEV_TX_OFFLOAD_TCP_TSO)) { ++ if (!(netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_TCP_TSO)) { + #endif + if (netif_mtu6(netif) && (p->tot_len > nd6_get_destination_mtu(dest, netif))) { + return ip6_frag(p, netif, dest); +diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c +index d6f54b6..bdd9a04 100644 +--- a/src/core/tcp_in.c ++++ b/src/core/tcp_in.c +@@ -209,7 +209,7 @@ tcp_input(struct pbuf *p, struct netif *inp) + /* Verify TCP checksum. */ + #if CHECKSUM_CHECK_TCP_HW + u64_t ret; +- if (netif_get_rxol_flags(inp) & DEV_RX_OFFLOAD_TCP_CKSUM) { ++ if (netif_get_rxol_flags(inp) & RTE_ETH_RX_OFFLOAD_TCP_CKSUM) { + ret = is_cksum_bad(p); + } else { + ret = (u64_t)ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, +diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c +index c5c81ae..30cd215 100644 +--- a/src/core/tcp_out.c ++++ b/src/core/tcp_out.c +@@ -1555,7 +1555,7 @@ tcp_output(struct tcp_pcb *pcb) + + /* data available and window allows it to be sent? */ + #if GAZELLE_ENABLE +- if ((netif_get_txol_flags(netif) & DEV_TX_OFFLOAD_TCP_TSO) && pcb->need_tso_send) { ++ if ((netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_TCP_TSO) && pcb->need_tso_send) { + uint16_t send_pkt = 0; + + do { +@@ -1938,7 +1938,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif + #if CHECKSUM_GEN_TCP + IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { + #if CHECKSUM_GEN_TCP_HW +- if (netif_get_txol_flags(netif) & DEV_TX_OFFLOAD_TCP_CKSUM) { ++ if (netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) { + tcph_cksum_set(seg->p, TCPH_HDRLEN_BYTES(seg->tcphdr)); + seg->tcphdr->chksum = ip_chksum_pseudo_offload(IP_PROTO_TCP,seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); + } else { +@@ -2398,7 +2398,7 @@ tcp_output_control_segment_netif(const struct tcp_pcb *pcb, struct pbuf *p, + IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { + struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload; + #if CHECKSUM_GEN_TCP_HW +- if (netif_get_txol_flags(netif) & DEV_TX_OFFLOAD_TCP_CKSUM) { ++ if (netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) { + tcph_cksum_set(p, TCPH_HDRLEN_BYTES(tcphdr)); + tcphdr->chksum = ip_chksum_pseudo_offload(IP_PROTO_TCP, p->tot_len, src, dst); + } else { +diff --git a/src/core/udp.c b/src/core/udp.c +index ca82e51..461ec2d 100644 +--- a/src/core/udp.c ++++ b/src/core/udp.c +@@ -414,7 +414,7 @@ udp_input(struct pbuf *p, struct netif *inp) + if (udphdr->chksum != 0) { + #if CHECKSUM_CHECK_UDP_HW + u64_t ret = 0; +- if (netif_get_rxol_flags(inp) & DEV_RX_OFFLOAD_UDP_CKSUM) { ++ if (netif_get_rxol_flags(inp) & RTE_ETH_RX_OFFLOAD_UDP_CKSUM) { + ret = is_cksum_bad(p); + } else { + ret = ip_chksum_pseudo(p, IP_PROTO_UDP, p->tot_len, +@@ -983,7 +983,7 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d + #endif /* LWIP_CHECKSUM_ON_COPY */ + { + #if CHECKSUM_GEN_UDP_HW +- if (netif_get_txol_flags(netif) & DEV_TX_OFFLOAD_UDP_CKSUM) { ++ if (netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) { + udph_cksum_set(q, UDP_HLEN); + udpchksum = ip_chksum_pseudo_offload(IP_PROTO_UDP, q->tot_len, &pcb->local_ip, &pcb->remote_ip); + } else { +diff --git a/src/include/dpdk_version.h b/src/include/dpdk_version.h +index 5efaa39..df3adb5 100644 +--- a/src/include/dpdk_version.h ++++ b/src/include/dpdk_version.h +@@ -33,23 +33,47 @@ + #ifndef __DPDK_VERSION_H__ + #define __DPDK_VERSION_H__ + +-#if DPDK_VERSION_1911 ++#include ++ ++#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) + #define __rte_ring_enqueue_elems(r, prod_head, obj_table, esize, n) \ + ENQUEUE_PTRS(r, &r[1], prod_head, (obj_table), n, void *) + + #define __rte_ring_dequeue_elems(r, cons_head, obj_table, esize, n) \ + DEQUEUE_PTRS(r, &r[1], cons_head, (obj_table), n, void *) + +-#define RTE_MBUF_F_RX_IP_CKSUM_BAD PKT_RX_IP_CKSUM_BAD +-#define RTE_MBUF_F_RX_L4_CKSUM_BAD PKT_RX_L4_CKSUM_BAD +-#define RTE_MBUF_F_TX_IPV4 PKT_TX_IPV4 +-#define RTE_MBUF_F_TX_IPV6 PKT_TX_IPV6 +-#define RTE_MBUF_F_TX_IP_CKSUM PKT_TX_IP_CKSUM +-#define RTE_MBUF_F_TX_TCP_CKSUM PKT_TX_TCP_CKSUM +-#define RTE_MBUF_F_TX_TCP_SEG PKT_TX_TCP_SEG +-#define RTE_MBUF_F_TX_UDP_CKSUM PKT_TX_UDP_CKSUM +-#define RTE_MBUF_F_TX_VLAN PKT_TX_VLAN_PKT +- +-#endif /* DPDK_VERSION_1911 */ ++#define RTE_MBUF_F_RX_IP_CKSUM_BAD PKT_RX_IP_CKSUM_BAD ++#define RTE_MBUF_F_RX_L4_CKSUM_BAD PKT_RX_L4_CKSUM_BAD ++#define RTE_MBUF_F_TX_IPV4 PKT_TX_IPV4 ++#define RTE_MBUF_F_TX_IPV6 PKT_TX_IPV6 ++#define RTE_MBUF_F_TX_IP_CKSUM PKT_TX_IP_CKSUM ++#define RTE_MBUF_F_TX_TCP_CKSUM PKT_TX_TCP_CKSUM ++#define RTE_MBUF_F_TX_TCP_SEG PKT_TX_TCP_SEG ++#define RTE_MBUF_F_TX_UDP_CKSUM PKT_TX_UDP_CKSUM ++#define RTE_MBUF_F_TX_VLAN PKT_TX_VLAN_PKT ++ ++#define RTE_ETH_RX_OFFLOAD_TCP_CKSUM DEV_RX_OFFLOAD_TCP_CKSUM ++#define RTE_ETH_RX_OFFLOAD_UDP_CKSUM DEV_RX_OFFLOAD_UDP_CKSUM ++#define RTE_ETH_RX_OFFLOAD_IPV4_CKSUM DEV_RX_OFFLOAD_IPV4_CKSUM ++#define RTE_ETH_RX_OFFLOAD_VLAN_STRIP DEV_RX_OFFLOAD_VLAN_STRIP ++ ++#define RTE_ETH_TX_OFFLOAD_IPV4_CKSUM DEV_TX_OFFLOAD_IPV4_CKSUM ++#define RTE_ETH_TX_OFFLOAD_VLAN_INSERT DEV_TX_OFFLOAD_VLAN_INSERT ++#define RTE_ETH_TX_OFFLOAD_TCP_TSO DEV_TX_OFFLOAD_TCP_TSO ++#define RTE_ETH_TX_OFFLOAD_TCP_CKSUM DEV_TX_OFFLOAD_TCP_CKSUM ++#define RTE_ETH_TX_OFFLOAD_UDP_CKSUM DEV_TX_OFFLOAD_UDP_CKSUM ++#define RTE_ETH_TX_OFFLOAD_MULTI_SEGS DEV_TX_OFFLOAD_MULTI_SEGS ++ ++#define RTE_ETH_LINK_SPEED_AUTONEG ETH_LINK_SPEED_AUTONEG ++ ++#define RTE_ETH_MQ_TX_NONE ETH_MQ_TX_NONE ++#define RTE_ETH_MQ_RX_NONE ETH_MQ_RX_NONE ++#define RTE_ETH_RSS_IP ETH_RSS_IP ++#define RTE_ETH_RSS_TCP ETH_RSS_TCP ++#define RTE_ETH_RSS_UDP ETH_RSS_UDP ++#define RTE_ETH_MQ_RX_RSS ETH_MQ_RX_RSS ++#define RTE_ETH_RETA_GROUP_SIZE RTE_RETA_GROUP_SIZE ++ ++#endif /* RTE_VERSION */ + + #endif /* __DPDK_VERSION_H__ */ +diff --git a/src/netif/ethernet.c b/src/netif/ethernet.c +index d2960b5..e049cdf 100644 +--- a/src/netif/ethernet.c ++++ b/src/netif/ethernet.c +@@ -289,7 +289,7 @@ ethernet_output(struct netif * netif, struct pbuf * p, + } + #else + if (netif->vlan_enable) { +- if (netif->txol_flags & DEV_TX_OFFLOAD_VLAN_INSERT) { ++ if (netif->txol_flags & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) { + p->ol_flags |= RTE_MBUF_F_TX_VLAN; + p->vlan_tci = netif->vlan_tci; + } else { +@@ -332,7 +332,7 @@ ethernet_output(struct netif * netif, struct pbuf * p, + ("ethernet_output: sending packet %p\n", (void *)p)); + + #if CHECKSUM_GEN_IP_HW || CHECKSUM_GEN_TCP_HW +- if (netif->vlan_enable && !(netif->txol_flags & DEV_TX_OFFLOAD_VLAN_INSERT)) { ++ if (netif->vlan_enable && !(netif->txol_flags & RTE_ETH_TX_OFFLOAD_VLAN_INSERT)) { + ethh_cksum_set(p, sizeof(*ethhdr) + SIZEOF_VLAN_HDR); + } else { + ethh_cksum_set(p, sizeof(*ethhdr)); +-- +2.33.0 + diff --git a/0104-optimize-enqueue-for-unacked-and-unsent-queue.patch b/0104-optimize-enqueue-for-unacked-and-unsent-queue.patch new file mode 100644 index 0000000..1c316c7 --- /dev/null +++ b/0104-optimize-enqueue-for-unacked-and-unsent-queue.patch @@ -0,0 +1,71 @@ +From d491c37cce3796ddce32b30be7ad23d52937479e Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 5 Feb 2024 19:18:52 +0800 +Subject: optimize enqueue for unacked and unsent queue + +--- + src/core/tcp_out.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c +index 30cd215..1ab5cfb 100644 +--- a/src/core/tcp_out.c ++++ b/src/core/tcp_out.c +@@ -1636,6 +1636,10 @@ tcp_output(struct tcp_pcb *pcb) + pbuf_remove_header(new_seg.p, new_seg.p->tot_len - new_seg.len - TCP_HLEN); + new_seg.p->tot_len = new_seg.p->len; + ++ struct tcp_seg **cur_seg = NULL; ++ if (pcb->unacked != NULL) { ++ cur_seg = &(pcb->unacked); ++ } + for (int start = pbuf_chain_len; start > 0; start--) { + struct tcp_seg *tmp_seg = start_seg; + start_seg = start_seg->next; +@@ -1646,10 +1650,10 @@ tcp_output(struct tcp_pcb *pcb) + pcb->last_unacked = tmp_seg; + pcb->unacked = tmp_seg; + useg = tmp_seg; ++ cur_seg = &(pcb->unacked); + } else { + if (TCP_SEQ_LT(lwip_ntohl(tmp_seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) { + /* add segment to before tail of unacked list, keeping the list sorted */ +- struct tcp_seg **cur_seg = &(pcb->unacked); + while (*cur_seg && + TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(tmp_seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); +@@ -2160,7 +2164,10 @@ tcp_rexmit(struct tcp_pcb *pcb) + } + + seg = pcb->unacked; ++#if GAZELLE_ENABLE ++ cur_seg = &(pcb->unsent); + while (seg) { ++#endif + /* Give up if the segment is still referenced by the netif driver + due to deferred transmission. */ + if (tcp_output_segment_busy(seg)) { +@@ -2177,7 +2184,9 @@ tcp_rexmit(struct tcp_pcb *pcb) + pcb->last_unacked = pcb->unacked->next; + pcb->unacked = pcb->unacked->next; + ++#if !GAZELLE_ENABLE + cur_seg = &(pcb->unsent); ++#endif + while (*cur_seg && + TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next); +@@ -2193,8 +2202,10 @@ tcp_rexmit(struct tcp_pcb *pcb) + } + #endif /* TCP_OVERSIZE */ + ++#if GAZELLE_ENABLE + seg = pcb->unacked; + } ++#endif + + if (pcb->nrtx < 0xFF) { + ++pcb->nrtx; +-- +2.33.0 + diff --git a/0105-delete-redundant-logs-in-lwip.patch b/0105-delete-redundant-logs-in-lwip.patch new file mode 100644 index 0000000..16877be --- /dev/null +++ b/0105-delete-redundant-logs-in-lwip.patch @@ -0,0 +1,91 @@ +From ed49e784233ec0a83eb4f4e37fe9cd112bfed555 Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Wed, 10 Jan 2024 09:31:23 +0800 +Subject: [PATCH] delete redundant logs in lwip + +--- + src/api/sockets.c | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index 250c424..082ae14 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -487,7 +487,7 @@ tryget_socket_unconn_nouse(int fd) + if ((s < 0) || (s >= NUM_SOCKETS)) + #endif /* GAZELLE_ENABLE */ + { +- LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("tryget_socket_unconn(%d): invalid\n", fd)); ++ LWIP_DEBUGF(SOCKETS_DEBUG , ("tryget_socket_unconn(%d): invalid\n", fd)); + return NULL; + } + return &sockets[s]; +@@ -561,7 +561,7 @@ get_socket(int fd) + struct lwip_sock *sock = tryget_socket(fd); + if (!sock) { + if ((fd < LWIP_SOCKET_OFFSET) || (fd >= (LWIP_SOCKET_OFFSET + NUM_SOCKETS))) { +- LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("get_socket(%d): invalid\n", fd)); ++ LWIP_DEBUGF(SOCKETS_DEBUG , ("get_socket(%d): invalid\n", fd)); + } + set_errno(EBADF); + return NULL; +@@ -628,7 +628,6 @@ alloc_socket(struct netconn *newconn, int accepted, int flags) + SYS_ARCH_PROTECT(lev); + i = posix_api->socket_fn(domain, type, protocol); + if (i == -1) { +- LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("posix_api->socket_fn fail socket is -1")); + goto err; + } + +@@ -637,7 +636,6 @@ alloc_socket(struct netconn *newconn, int accepted, int flags) + } + + if ((i < LWIP_SOCKET_OFFSET) || (i >= sockets_num + LWIP_SOCKET_OFFSET)) { +- LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("posix_api->socket_fn socket is %d, illegal\n", i)); + goto err; + } + +@@ -808,14 +806,13 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); + sock = get_socket(s); + if (!sock) { +- LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("get_socket sock is null\n")); + return -1; + } + + /* wait for a new connection */ + err = netconn_accept(sock->conn, &newconn); + if (err != ERR_OK) { +- LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); ++ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + set_errno(EOPNOTSUPP); + } else if (err == ERR_CLSD) { +@@ -830,7 +827,6 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) + + newsock = alloc_socket(newconn, 1, flags); + if (newsock == -1) { +- LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("alloc_socket fail newsock is -1\n")); + netconn_delete(newconn); + set_errno(ENFILE); + done_socket(sock); +@@ -850,7 +846,6 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) + ret = find_same_node_memzone(pcb, nsock); + } + if (pcb == NULL || ret != 0) { +- LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("alloc_socket fail pcb null flag=%u, ret=%d \n", (pcb == NULL), ret)); + netconn_delete(newconn); + free_socket(nsock, 1); + sock_set_errno(sock, ENOTCONN); +@@ -886,7 +881,7 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) + /* get the IP address and port of the remote host */ + err = netconn_peer(newconn, &naddr, &port); + if (err != ERR_OK) { +- LWIP_DEBUGF(SOCKETS_DEBUG | GAZELLE_DEBUG_SERIOUS, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); ++ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); + free_socket(nsock, 1); + set_errno(err_to_errno(err)); + done_socket(sock); +-- +2.33.0 + diff --git a/0106-remove-unnecessary-variables-in-struct-pbuf.patch b/0106-remove-unnecessary-variables-in-struct-pbuf.patch new file mode 100644 index 0000000..7e15c5f --- /dev/null +++ b/0106-remove-unnecessary-variables-in-struct-pbuf.patch @@ -0,0 +1,228 @@ +From bb07cd2f26a91c4f5396f2e19a409e4014e7a7e8 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Fri, 19 Jan 2024 20:44:54 +0800 +Subject: [PATCH] remove unnecessary variables in struct pbuf + +--- + src/core/pbuf.c | 5 ++-- + src/core/tcp_out.c | 3 +- + src/core/udp.c | 4 +-- + src/include/dpdk_cksum.h | 60 ++++++++++++++++++++-------------------- + src/include/lwip/pbuf.h | 12 -------- + src/netif/ethernet.c | 3 +- + 6 files changed, 36 insertions(+), 51 deletions(-) + +diff --git a/src/core/pbuf.c b/src/core/pbuf.c +index 8386c90..b0a63b4 100644 +--- a/src/core/pbuf.c ++++ b/src/core/pbuf.c +@@ -86,6 +86,7 @@ + #endif + #if GAZELLE_ENABLE + #include ++#include "dpdk_cksum.h" + #endif + + #include +@@ -1038,9 +1039,7 @@ pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_ + } + + #if GAZELLE_ENABLE && (CHECKSUM_GEN_IP_HW || CHECKSUM_GEN_TCP_HW) +- p_to->l2_len = p_from->l2_len; +- p_to->l3_len = p_from->l3_len; +- p_to->ol_flags = p_from->ol_flags; ++ pbuf_offload_copy(p_to, p_from); + #endif + + len = LWIP_MIN(copy_len, len); +diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c +index 1ab5cfb..70c4242 100644 +--- a/src/core/tcp_out.c ++++ b/src/core/tcp_out.c +@@ -1944,7 +1944,6 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif + #if CHECKSUM_GEN_TCP_HW + if (netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) { + tcph_cksum_set(seg->p, TCPH_HDRLEN_BYTES(seg->tcphdr)); +- seg->tcphdr->chksum = ip_chksum_pseudo_offload(IP_PROTO_TCP,seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); + } else { + #if TCP_CHECKSUM_ON_COPY + u32_t acc; +@@ -2408,10 +2407,10 @@ tcp_output_control_segment_netif(const struct tcp_pcb *pcb, struct pbuf *p, + #if CHECKSUM_GEN_TCP + IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { + struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload; ++ tcphdr->chksum = 0; + #if CHECKSUM_GEN_TCP_HW + if (netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) { + tcph_cksum_set(p, TCPH_HDRLEN_BYTES(tcphdr)); +- tcphdr->chksum = ip_chksum_pseudo_offload(IP_PROTO_TCP, p->tot_len, src, dst); + } else { + tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, + src, dst); +diff --git a/src/core/udp.c b/src/core/udp.c +index 461ec2d..440f909 100644 +--- a/src/core/udp.c ++++ b/src/core/udp.c +@@ -985,7 +985,7 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d + #if CHECKSUM_GEN_UDP_HW + if (netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) { + udph_cksum_set(q, UDP_HLEN); +- udpchksum = ip_chksum_pseudo_offload(IP_PROTO_UDP, q->tot_len, &pcb->local_ip, &pcb->remote_ip); ++ udpchksum = 0; + } else { + udpchksum = ip_chksum_pseudo(q, IP_PROTO_UDP, q->tot_len, + src_ip, dst_ip); +@@ -1019,7 +1019,7 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d + /* output to IP */ + NETIF_SET_HINTS(netif, &(pcb->netif_hints)); + #if GAZELLE_UDP_ENABLE +- q->l4_len = UDP_HLEN; ++ PBUF_TO_MBUF(q)->l4_len = UDP_HLEN; + #endif /* GAZELLE_UDP_ENABLE */ + err = ip_output_if_src(q, src_ip, dst_ip, ttl, pcb->tos, ip_proto, netif); + NETIF_RESET_HINTS(netif); +diff --git a/src/include/dpdk_cksum.h b/src/include/dpdk_cksum.h +index 38cfb96..115155d 100644 +--- a/src/include/dpdk_cksum.h ++++ b/src/include/dpdk_cksum.h +@@ -45,32 +45,48 @@ + #include "lwip/pbuf.h" + #endif + ++#define PBUF_TO_MBUF(p) ((struct rte_mbuf *)RTE_PTR_SUB(p, sizeof(struct rte_mbuf))) ++ ++static inline void pbuf_offload_copy(struct pbuf *to, const struct pbuf *from) ++{ ++ PBUF_TO_MBUF(to)->l4_len = PBUF_TO_MBUF(from)->l4_len; ++ PBUF_TO_MBUF(to)->l3_len = PBUF_TO_MBUF(from)->l3_len; ++ PBUF_TO_MBUF(to)->l2_len = PBUF_TO_MBUF(from)->l2_len; ++ PBUF_TO_MBUF(to)->ol_flags = PBUF_TO_MBUF(from)->ol_flags; ++} ++ ++static inline void pbuf_set_vlan(struct pbuf *p, u16_t vlan_tci) ++{ ++ PBUF_TO_MBUF(p)->ol_flags |= RTE_MBUF_F_TX_VLAN; ++ PBUF_TO_MBUF(p)->vlan_tci = vlan_tci; ++} ++ + #if CHECKSUM_CHECK_IP_HW + // for ip4_input + static inline u64_t is_cksum_ipbad(struct pbuf *p) { +- return p->ol_flags & (RTE_MBUF_F_RX_IP_CKSUM_BAD); ++ return PBUF_TO_MBUF(p)->ol_flags & (RTE_MBUF_F_RX_IP_CKSUM_BAD); + } + #endif /* CHECKSUM_CHECK_IP_HW */ + + #if (CHECKSUM_CHECK_TCP_HW || CHECKSUM_CHECK_UDP_HW) + // for tcp_input and udp_input + static inline u64_t is_cksum_bad(struct pbuf *p) { +- return p->ol_flags & (RTE_MBUF_F_RX_L4_CKSUM_BAD); ++ return PBUF_TO_MBUF(p)->ol_flags & (RTE_MBUF_F_RX_L4_CKSUM_BAD); + } + #endif /* (CHECKSUM_CHECK_TCP_HW || CHECKSUM_CHECK_UDP_HW) */ + + #if CHECKSUM_GEN_IP_HW + static inline void ethh_cksum_set(struct pbuf *p, u16_t len) { +- p->l2_len = len; ++ PBUF_TO_MBUF(p)->l2_len = len; + } + + // replaces IPH_CHKSUM_SET + static inline void iph_cksum_set(struct pbuf *p, u16_t len, bool do_ipcksum) { +- p->ol_flags |= ((len == IP_HLEN) ? RTE_MBUF_F_TX_IPV4 : RTE_MBUF_F_TX_IPV6); ++ PBUF_TO_MBUF(p)->ol_flags |= ((len == IP_HLEN) ? RTE_MBUF_F_TX_IPV4 : RTE_MBUF_F_TX_IPV6); + if (do_ipcksum) { +- p->ol_flags |= RTE_MBUF_F_TX_IP_CKSUM; ++ PBUF_TO_MBUF(p)->ol_flags |= RTE_MBUF_F_TX_IP_CKSUM; + } +- p->l3_len = len; ++ PBUF_TO_MBUF(p)->l3_len = len; + } + #endif /* CHECKSUM_GEN_IP_HW */ + +@@ -80,37 +96,17 @@ static inline void iph_cksum_set(struct pbuf *p, u16_t len, bool do_ipcksum) { + + #if CHECKSUM_GEN_TCP_HW + static inline void tcph_cksum_set(struct pbuf *p, u16_t len) { +- p->l4_len = len; +- p->ol_flags |= RTE_MBUF_F_TX_TCP_CKSUM; ++ PBUF_TO_MBUF(p)->l4_len = len; ++ PBUF_TO_MBUF(p)->ol_flags |= RTE_MBUF_F_TX_TCP_CKSUM; + } + #endif /* CHECKSUM_GEN_TCP_HW */ + + #if CHECKSUM_GEN_UDP_HW + static inline void udph_cksum_set(struct pbuf *p, u16_t len) { +- p->l4_len = len; +- p->ol_flags |= RTE_MBUF_F_TX_UDP_CKSUM; ++ PBUF_TO_MBUF(p)->l4_len = len; ++ PBUF_TO_MBUF(p)->ol_flags |= RTE_MBUF_F_TX_UDP_CKSUM; + } + #endif /* CHECKSUM_GEN_UDP_HW */ +- +-static inline u16_t ip_chksum_pseudo_offload(u8_t proto, u16_t proto_len, +- const ip_addr_t *src, const ip_addr_t *dst) +-{ +- struct ip_psd_header { +- ip_addr_t src_addr; /* IP address of source host. */ +- ip_addr_t dst_addr; /* IP address of destination host. */ +- uint8_t zero; /* zero. */ +- uint8_t proto; /* L4 protocol type. */ +- uint16_t len; /* L4 length. */ +- } psd_hdr; +- +- ip_addr_copy(psd_hdr.src_addr, *src); +- ip_addr_copy(psd_hdr.dst_addr, *dst); +- psd_hdr.proto = proto; +- psd_hdr.len = lwip_htons(proto_len); +- psd_hdr.zero = 0; +- +- return rte_raw_cksum(&psd_hdr, sizeof(psd_hdr)); +-} + #endif /* (CHECKSUM_GEN_TCP_HW || CHECKSUM_GEN_UDP_HW) */ + + #endif /* GAZELLE_ENABLE */ +diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h +index bc29372..d84c9da 100644 +--- a/src/include/lwip/pbuf.h ++++ b/src/include/lwip/pbuf.h +@@ -225,22 +225,9 @@ struct pbuf { + u8_t if_idx; + + #if GAZELLE_ENABLE && CHECKSUM_OFFLOAD_ALL +- /** checksum offload ol_flags */ +- u64_t ol_flags; +- /* < L2 (MAC) Header Length for non-tunneling pkt. */ +- u64_t l2_len:7; +- /* < L3 (IP) Header Length. */ +- u64_t l3_len:9; +- /* < L4 (TCP/UDP) Header Length. */ +- u64_t l4_len:8; +- u8_t header_off; +- u8_t rexmit; + volatile u8_t allow_in; +- u8_t head; +- struct pbuf *last; + pthread_spinlock_t pbuf_lock; + struct tcp_pcb *pcb; +- u16_t vlan_tci; + #if GAZELLE_UDP_ENABLE + ip_addr_t addr; + u16_t port; +diff --git a/src/netif/ethernet.c b/src/netif/ethernet.c +index e049cdf..0d8652b 100644 +--- a/src/netif/ethernet.c ++++ b/src/netif/ethernet.c +@@ -290,8 +290,7 @@ ethernet_output(struct netif * netif, struct pbuf * p, + #else + if (netif->vlan_enable) { + if (netif->txol_flags & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) { +- p->ol_flags |= RTE_MBUF_F_TX_VLAN; +- p->vlan_tci = netif->vlan_tci; ++ pbuf_set_vlan(p, netif->vlan_tci); + } else { + vlan_prio_vid = netif->vlan_tci; + } +-- +2.33.0 + diff --git a/0107-fix-move-lpcb-to-the-front-of-list-error.patch b/0107-fix-move-lpcb-to-the-front-of-list-error.patch new file mode 100644 index 0000000..7d68411 --- /dev/null +++ b/0107-fix-move-lpcb-to-the-front-of-list-error.patch @@ -0,0 +1,27 @@ +From e2754cc316ca1fadabfbd8c927275a0d0d50d867 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Tue, 30 Jan 2024 15:38:13 +0800 +Subject: [PATCH] fix move lpcb to the front of list error + +--- + src/core/tcp_in.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c +index ec1905f..9d5a695 100644 +--- a/src/core/tcp_in.c ++++ b/src/core/tcp_in.c +@@ -454,6 +454,10 @@ tcp_input(struct pbuf *p, struct netif *inp) + /* our successor is the remainder of the listening list */ + lpcb->next = tcp_listen_pcbs.listen_pcbs; + #if GAZELLE_ENABLE ++ /* prev is head */ ++ if (prev->prev == NULL) { ++ prev->prev = (struct tcp_pcb *)lpcb; ++ } + lpcb->prev = NULL; + #endif + /* put this listening pcb at the head of the listening list */ +-- +2.33.0 + diff --git a/0108-fix-receive-fin-packet-process-error.patch b/0108-fix-receive-fin-packet-process-error.patch new file mode 100644 index 0000000..3dae612 --- /dev/null +++ b/0108-fix-receive-fin-packet-process-error.patch @@ -0,0 +1,59 @@ +From 7dbceaeab7f85df6a58b77858c507fa9087d5ba7 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 22 Jan 2024 20:38:57 +0800 +Subject: [PATCH] fix receive fin packet process error + +--- + src/core/tcp_in.c | 9 --------- + src/include/lwipsock.h | 1 + + 2 files changed, 1 insertion(+), 9 deletions(-) + +diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c +index 9d5a695..84d22ca 100644 +--- a/src/core/tcp_in.c ++++ b/src/core/tcp_in.c +@@ -1142,9 +1142,6 @@ tcp_process(struct tcp_pcb *pcb) + if (recv_flags & TF_GOT_FIN) { + tcp_ack_now(pcb); + pcb->state = CLOSE_WAIT; +-#if GAZELLE_ENABLE +- API_EVENT(((struct netconn *)pcb->callback_arg), NETCONN_EVT_ERROR, 0); +-#endif + } + } else { + /* incorrect ACK number, send RST */ +@@ -1163,9 +1160,6 @@ tcp_process(struct tcp_pcb *pcb) + if (recv_flags & TF_GOT_FIN) { /* passive close */ + tcp_ack_now(pcb); + pcb->state = CLOSE_WAIT; +-#if GAZELLE_ENABLE +- API_EVENT(((struct netconn *)pcb->callback_arg), NETCONN_EVT_ERROR, 0); +-#endif + } + break; + case FIN_WAIT_1: +@@ -1820,9 +1814,6 @@ tcp_receive(struct tcp_pcb *pcb) + recv_flags |= TF_GOT_FIN; + if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ + pcb->state = CLOSE_WAIT; +-#if GAZELLE_ENABLE +- API_EVENT(((struct netconn *)pcb->callback_arg), NETCONN_EVT_ERROR, 0); +-#endif + } + } + +diff --git a/src/include/lwipsock.h b/src/include/lwipsock.h +index ccc8c43..f4cb1de 100644 +--- a/src/include/lwipsock.h ++++ b/src/include/lwipsock.h +@@ -120,7 +120,6 @@ struct lwip_sock { + char pad2 __rte_cache_aligned; + /* stack thread all use */ + struct list_node recv_list; +- struct pbuf *send_lastdata; + struct pbuf *send_pre_del; + sem_t snd_ring_sem; + +-- +2.33.0 + diff --git a/0109-support-udp-recv-zero-packets.patch b/0109-support-udp-recv-zero-packets.patch new file mode 100644 index 0000000..4b37939 --- /dev/null +++ b/0109-support-udp-recv-zero-packets.patch @@ -0,0 +1,25 @@ +From cbde011450b38359d494bcc18ae91c690e5c5d43 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Fri, 26 Jan 2024 17:28:29 +0800 +Subject: [PATCH] support udp recv zero packets + +--- + src/api/sockets.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index d8b41e4..c133fc2 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -1385,7 +1385,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 + LWIP_UNUSED_ARG(copied); + LWIP_UNUSED_ARG(i); + buflen = do_lwip_read_from_lwip(sock, flags, apiflags); +- if (buflen <= 0) { ++ if (buflen < 0) { + return ERR_BUF; + } + +-- +2.33.0 + diff --git a/0110-adapt-lwip-2.2.0.patch b/0110-adapt-lwip-2.2.0.patch new file mode 100644 index 0000000..f175cce --- /dev/null +++ b/0110-adapt-lwip-2.2.0.patch @@ -0,0 +1,126 @@ +From d0251f285bb997cdc0dc1e7ab28ba431bce9c544 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 5 Feb 2024 19:56:58 +0800 +Subject: [PATCH] adapt lwip 2.2.0 + +--- + src/api/api_msg.c | 8 ++++---- + src/api/sockets.c | 23 +++++++---------------- + src/core/tcp.c | 4 ++-- + src/core/tcp_out.c | 2 +- + src/include/lwipopts.h | 2 +- + 5 files changed, 15 insertions(+), 24 deletions(-) + +diff --git a/src/api/api_msg.c b/src/api/api_msg.c +index adfdd40..a0baaae 100644 +--- a/src/api/api_msg.c ++++ b/src/api/api_msg.c +@@ -295,7 +295,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, + SYS_ARCH_INC(conn->recv_avail, len); + #endif /* LWIP_SO_RCVBUF */ + #if GAZELLE_UDP_ENABLE +- do_lwip_add_recvlist(conn->socket); ++ do_lwip_add_recvlist(conn->callback_arg.socket); + #endif /* GAZELLE_UDP_ENABLE */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); +@@ -357,7 +357,7 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) + SYS_ARCH_INC(conn->recv_avail, len); + #endif /* LWIP_SO_RCVBUF */ + #if GAZELLE_ENABLE +- do_lwip_add_recvlist(conn->socket); ++ do_lwip_add_recvlist(conn->callback_arg.socket); + #endif + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); +@@ -491,7 +491,7 @@ err_tcp(void *arg, err_t err) + /* use trypost to prevent deadlock */ + sys_mbox_trypost(&conn->recvmbox, mbox_msg); + #if GAZELLE_ENABLE +- do_lwip_add_recvlist(conn->socket); ++ do_lwip_add_recvlist(conn->callback_arg.socket); + #endif + } + /* pass error message to acceptmbox to wake up pending accept */ +diff --git a/src/api/sockets.c b/src/api/sockets.c +index e6868a1..923518c 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -848,7 +848,7 @@ lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) + if (pcb == NULL || ret != 0) { + netconn_delete(newconn); + free_socket(nsock, 1); +- sock_set_errno(sock, ENOTCONN); ++ set_errno(ENOTCONN); + done_socket(sock); + return -1; + } +@@ -2840,7 +2840,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) + break; + case NETCONN_EVT_ERROR: + if ((conn->pending_err != ERR_OK) && (conn->pending_err != ERR_RST)) { +- LWIP_DEBUGF(GAZELLE_DEBUG_SERIOUS, ("event_callback: have errevent, err=%d, fd=%d\n", conn->pending_err, conn->socket)); ++ LWIP_DEBUGF(GAZELLE_DEBUG_SERIOUS, ("event_callback: have errevent, err=%d, fd=%d\n", conn->pending_err, conn->callback_arg.socket)); + } + sock->errevent = 1; + #if GAZELLE_ENABLE +@@ -4246,7 +4246,7 @@ lwip_fcntl(int s, int cmd, int val) + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); + #if GAZELLE_ENABLE +- sock_errno(sock, 0); /* not yet implemented, but we return 0 for compatilbe with app */ ++ set_errno(0); /* not yet implemented, but we return 0 for compatilbe with app */ + ret = 0; + #else + set_errno(ENOSYS); /* not yet implemented */ +diff --git a/src/core/tcp.c b/src/core/tcp.c +index a9a6513..69f6953 100644 +--- a/src/core/tcp.c ++++ b/src/core/tcp.c +@@ -258,7 +258,7 @@ tcp_free(struct tcp_pcb *pcb) + rte_ring_free(pcb->client_rx_ring); + rte_ring_free(pcb->client_tx_ring); + netconn = (struct netconn *)pcb->callback_arg; +- sock = get_socket(netconn->socket); ++ sock = get_socket(netconn->callback_arg.socket); + rte_memzone_free(sock->same_node_rx_ring->mz); + rte_memzone_free(sock->same_node_rx_ring_mz); + rte_memzone_free(sock->same_node_tx_ring->mz); +@@ -995,7 +995,7 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u16_t backlog, err_t *err) + lpcb->next_same_port_pcb = NULL; + + struct netconn* conn = pcb->callback_arg; +- lpcb->socket_fd = conn->socket; ++ lpcb->socket_fd = conn->callback_arg.socket; + lpcb->master_lpcb = conn->is_master_fd; + #endif + +diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c +index 70c4242..1632a66 100644 +--- a/src/core/tcp_out.c ++++ b/src/core/tcp_out.c +@@ -2501,7 +2501,7 @@ tcp_rst(const struct tcp_pcb *pcb, u32_t seqno, u32_t ackno, + + p = tcp_rst_common(pcb, seqno, ackno, local_ip, remote_ip, local_port, remote_port); + if (p != NULL) { +- tcp_output_control_segment(pcb, p, local_ip, remote_ip); ++ tcp_output_control_segment((struct tcp_pcb *)pcb, p, local_ip, remote_ip); + } + } + +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index d54ff1e..28b8aca 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h +@@ -107,7 +107,7 @@ + + #define LWIP_TIMERS 1 + +-#define TCP_SND_BUF (2500 * TCP_MSS) ++#define LWIP_TIMEVAL_PRIVATE 0 + + /* + ------------------------------------------------ +-- +2.33.0 + diff --git a/0111-support-udp-pkglen-mtu-modify-IP_REASS_MAX_PBUFS.patch b/0111-support-udp-pkglen-mtu-modify-IP_REASS_MAX_PBUFS.patch new file mode 100644 index 0000000..895ab7e --- /dev/null +++ b/0111-support-udp-pkglen-mtu-modify-IP_REASS_MAX_PBUFS.patch @@ -0,0 +1,26 @@ +From b619f034c74d53bd6d8b572cb47fdb58fd90d7ae Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Wed, 6 Mar 2024 11:00:56 +0800 +Subject: [PATCH] support udp pkglen > mtu: modify IP_REASS_MAX_PBUFS + +--- + src/include/lwipopts.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index 28b8aca..d067dea 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h +@@ -171,6 +171,9 @@ + + #define IP_HLEN 20 + ++/* the max pbuf num of a udp pbuf chain is ((65535 + MBUF_MAX_DATA_LEN - 1) / MBUF_MAX_DATA_LEN) */ ++#define IP_REASS_MAX_PBUFS 46 ++ + /* + ------------------------------------- + ----------- IPv6 options ----------- +-- +2.33.0 + diff --git a/0112-support-udp-pkglen-mtu-modify-netbuf_alloc-size.patch b/0112-support-udp-pkglen-mtu-modify-netbuf_alloc-size.patch new file mode 100644 index 0000000..58068f9 --- /dev/null +++ b/0112-support-udp-pkglen-mtu-modify-netbuf_alloc-size.patch @@ -0,0 +1,38 @@ +From 1e4e2fe5d7239da26edf89f554f929c10e0d5573 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Wed, 6 Mar 2024 18:25:19 +0800 +Subject: [PATCH] support udp pkglen > mtu: modify netbuf_alloc size + +--- + src/api/sockets.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index 923518c..66f6e2c 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -1891,7 +1891,13 @@ lwip_sendto(int s, const void *data, size_t size, int flags, + /* make the buffer point to the data that should be sent */ + #if LWIP_NETIF_TX_SINGLE_PBUF + /* Allocate a new netbuf and copy the data into it. */ ++#if GAZELLE_ENABLE ++ /* In the gazelle scenario, only use buf.p->payload and buf.p->tot_len, and ++ buf.p->payload stores the sock pointer info. Don't need to alloc short_size */ ++ if (netbuf_alloc(&buf, 0) == NULL) { ++#else + if (netbuf_alloc(&buf, short_size) == NULL) { ++#endif + err = ERR_MEM; + } else { + #if LWIP_CHECKSUM_ON_COPY +@@ -1905,6 +1911,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags, + /* In the gazelle scenario, the payload is stored in send_ring, + and the payload stores the sock pointer information. */ + buf.p->payload = (void *)sock; ++ buf.p->tot_len = short_size; + #else + MEMCPY(buf.p->payload, data, short_size); + #endif +-- +2.33.0 + diff --git a/0113-fix-duplicate-pbuf_free-in-udp_sendto.patch b/0113-fix-duplicate-pbuf_free-in-udp_sendto.patch new file mode 100644 index 0000000..30c7aa5 --- /dev/null +++ b/0113-fix-duplicate-pbuf_free-in-udp_sendto.patch @@ -0,0 +1,24 @@ +From 3b0bca4b38276c95f1305247ebf8a3db02ff5d83 Mon Sep 17 00:00:00 2001 +From: liyunqing +Date: Thu, 7 Mar 2024 11:18:00 +0800 +Subject: [PATCH] fix duplicate pbuf_free in udp_sendto + +--- + src/core/udp.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/core/udp.c b/src/core/udp.c +index 440f909..ff5c99b 100644 +--- a/src/core/udp.c ++++ b/src/core/udp.c +@@ -680,7 +680,6 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, + struct pbuf *udp_pbuf = do_lwip_get_from_sendring((struct lwip_sock *)(p->payload), p->tot_len, &apiflags); + do_lwip_get_from_sendring_over((struct lwip_sock *)(p->payload)); + +- pbuf_free(p); + p = udp_pbuf; + if (p == NULL) { + return ERR_MEM; +-- +2.27.0 + diff --git a/0114-sync-recv-flags-with-linux-kernel.patch b/0114-sync-recv-flags-with-linux-kernel.patch new file mode 100644 index 0000000..33266c9 --- /dev/null +++ b/0114-sync-recv-flags-with-linux-kernel.patch @@ -0,0 +1,40 @@ +From 931c9ff6d250685ce29cf10e3e03ecaae70419ea Mon Sep 17 00:00:00 2001 +From: liyunqing +Date: Tue, 27 Feb 2024 15:40:33 +0800 +Subject: [PATCH] sync recv flags with linux kernel + +--- + src/include/lwip/sockets.h | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h +index 89b6eb5..4466f11 100644 +--- a/src/include/lwip/sockets.h ++++ b/src/include/lwip/sockets.h +@@ -281,14 +281,22 @@ struct linger { + #define IPPROTO_UDPLITE 136 + #define IPPROTO_RAW 255 + ++#if GAZELLE_ENABLE + /* Flags we can use with send and recv. */ ++#define MSG_PEEK 0x02 /* Peeks at an incoming message */ ++#define MSG_WAITALL 0x100 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */ ++#define MSG_OOB 0x01 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ ++#define MSG_DONTWAIT 0x40 /* Nonblocking i/o for this operation only */ ++#define MSG_MORE 0x8000 /* Sender will send more */ ++#define MSG_NOSIGNAL 0x4000 /* Uninmplemented: Requests not to send the SIGPIPE signal if an attempt to send is made on a stream-oriented socket that is no longer connected. */ ++#else + #define MSG_PEEK 0x01 /* Peeks at an incoming message */ + #define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */ + #define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ + #define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */ + #define MSG_MORE 0x10 /* Sender will send more */ + #define MSG_NOSIGNAL 0x20 /* Uninmplemented: Requests not to send the SIGPIPE signal if an attempt to send is made on a stream-oriented socket that is no longer connected. */ +- ++#endif /* GAZELLE_ENABLE */ + + /* + * Options for level IPPROTO_IP +-- +2.27.0 + diff --git a/0115-enable-LWIP_SO_RCVTIMEO-to-support-recv-accept-timeo.patch b/0115-enable-LWIP_SO_RCVTIMEO-to-support-recv-accept-timeo.patch new file mode 100644 index 0000000..3f2e23d --- /dev/null +++ b/0115-enable-LWIP_SO_RCVTIMEO-to-support-recv-accept-timeo.patch @@ -0,0 +1,25 @@ +From f0ca9ad7361b943c0ce84bad8dc2655a90e38ca4 Mon Sep 17 00:00:00 2001 +From: liyunqing +Date: Fri, 15 Mar 2024 17:49:27 +0800 +Subject: [PATCH] enable LWIP_SO_RCVTIMEO to support recv\accept timeout + +--- + src/include/lwipopts.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index d067dea..3b8de83 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h +@@ -257,6 +257,8 @@ + + #define SIOCSHIWAT 1 + ++#define LWIP_SO_RCVTIMEO 1 ++ + /* + ------------------------------------ + --------- Debug log options -------- +-- +2.27.0 + diff --git a/0116-transfer-pbuf-timestamp-in-ip-frag.patch b/0116-transfer-pbuf-timestamp-in-ip-frag.patch new file mode 100644 index 0000000..d8dce59 --- /dev/null +++ b/0116-transfer-pbuf-timestamp-in-ip-frag.patch @@ -0,0 +1,48 @@ +From 08db0069d623d35de69999ba1dfbc9ed1a5b78d6 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Thu, 14 Mar 2024 16:49:56 +0800 +Subject: [PATCH] transfer pbuf timestamp in ip frag + +--- + src/core/ipv4/ip4_frag.c | 5 +++++ + src/include/lwipsock.h | 1 + + 2 files changed, 6 insertions(+) + +diff --git a/src/core/ipv4/ip4_frag.c b/src/core/ipv4/ip4_frag.c +index d9bf5cc..aa50856 100644 +--- a/src/core/ipv4/ip4_frag.c ++++ b/src/core/ipv4/ip4_frag.c +@@ -39,6 +39,7 @@ + */ + + #include "lwip/opt.h" ++#include "lwipsock.h" + + #if LWIP_IPV4 + +@@ -800,6 +801,10 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest) + if (rambuf == NULL) { + goto memerr; + } ++#if GAZELLE_ENABLE ++ /* transfer time stamp to new pbuf */ ++ time_stamp_transfer_pbuf(p, rambuf); ++#endif + LWIP_ASSERT("this needs a pbuf in one piece!", + (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); + poff += pbuf_copy_partial(p, rambuf->payload, fragsize, poff); +diff --git a/src/include/lwipsock.h b/src/include/lwipsock.h +index f4cb1de..dc2e9d3 100644 +--- a/src/include/lwipsock.h ++++ b/src/include/lwipsock.h +@@ -182,6 +182,7 @@ extern err_t same_node_ring_create(struct rte_ring **ring, int size, int port, c + extern err_t create_same_node_ring(struct tcp_pcb *pcb); + extern err_t find_same_node_ring(struct tcp_pcb *pcb); + extern void lstack_calculate_aggregate(int type, uint32_t len); ++extern void time_stamp_transfer_pbuf(struct pbuf *pbuf_old, struct pbuf *pbuf_new); + #endif /* GAZELLE_ENABLE */ + + struct lwip_sock *get_socket(int s); +-- +2.33.0 + diff --git a/0117-udp-muticast-loop.patch b/0117-udp-muticast-loop.patch new file mode 100644 index 0000000..bd67623 --- /dev/null +++ b/0117-udp-muticast-loop.patch @@ -0,0 +1,70 @@ +From 74d87ad663f013e792a9ea5d004eae139cd2e0a0 Mon Sep 17 00:00:00 2001 +From: compile_success <980965867@qq.com> +Date: Sat, 9 Mar 2024 06:45:25 +0000 +Subject: [PATCH] support loop mode + +--- + src/core/netif.c | 8 ++++++++-- + src/include/lwip/netif.h | 4 ++++ + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/core/netif.c b/src/core/netif.c +index 8302bd5..79f2317 100644 +--- a/src/core/netif.c ++++ b/src/core/netif.c +@@ -1117,6 +1117,10 @@ netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callb + */ + err_t + netif_loop_output(struct netif *netif, struct pbuf *p) ++#else ++err_t ++udp_netif_loop_output(struct netif *netif, struct pbuf *p) ++#endif + { + struct pbuf *r; + err_t err; +@@ -1218,7 +1224,6 @@ netif_loop_output(struct netif *netif, struct pbuf *p) + + return ERR_OK; + } +-#endif + + #if LWIP_HAVE_LOOPIF + #if LWIP_IPV4 +@@ -1249,6 +1254,10 @@ netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ad + */ + void + netif_poll(struct netif *netif) ++#else ++void ++udp_netif_poll(struct netif *netif) ++#endif + { + /* If we have a loopif, SNMP counters are adjusted for it, + * if not they are adjusted for 'netif'. */ +@@ -1312,7 +1321,6 @@ netif_poll(struct netif *netif) + } + SYS_ARCH_UNPROTECT(lev); + } +-#endif + + #if !LWIP_NETIF_LOOPBACK_MULTITHREADING + /** +diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h +index d10d4e8..d8f1f45 100644 +--- a/src/include/lwip/netif.h ++++ b/src/include/lwip/netif.h +@@ -538,6 +538,10 @@ void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_ + #if ENABLE_LOOPBACK + err_t netif_loop_output(struct netif *netif, struct pbuf *p); + void netif_poll(struct netif *netif); ++#if GAZELLE_ENABLE ++err_t udp_netif_loop_output(struct netif *netif, struct pbuf *p); ++void udp_netif_poll(struct netif *netif); ++#endif + #if !LWIP_NETIF_LOOPBACK_MULTITHREADING + void netif_poll_all(void); + #endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ +-- +2.33.0 + diff --git a/0118-support-querying-udp-multicast-addresses.patch b/0118-support-querying-udp-multicast-addresses.patch new file mode 100644 index 0000000..1169f42 --- /dev/null +++ b/0118-support-querying-udp-multicast-addresses.patch @@ -0,0 +1,128 @@ +From 0ba2b637ae7ae725bdd7de24de58b517a0cce93f Mon Sep 17 00:00:00 2001 +From: wuchangye +Date: Sun, 24 Mar 2024 05:29:30 +0800 +Subject: [PATCH] support querying udp multicast addresses + +--- + src/api/sockets.c | 43 ++++++++++++++++++++++++++++++++++++-- + src/include/lwip/sockets.h | 1 + + 2 files changed, 42 insertions(+), 2 deletions(-) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index 66f6e2c..c544c22 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -4342,6 +4342,27 @@ lwip_inet_pton(int af, const char *src, void *dst) + } + + #if LWIP_IGMP ++#if GAZELLE_ENABLE ++int lwip_socket_get_multi_memberships(int s, ip4_addr_t *if_addr, ip4_addr_t *multi_addr) ++{ ++ struct lwip_sock *sock = get_socket(s); ++ ++ if (!sock) { ++ return 0; ++ } ++ ++ if (socket_ipv4_multicast_memberships[s].sock == sock) { ++ ip4_addr_copy(*if_addr, socket_ipv4_multicast_memberships[s].if_addr); ++ ip4_addr_copy(*multi_addr, socket_ipv4_multicast_memberships[s].multi_addr); ++ done_socket(sock); ++ return 1; ++ } ++ ++ done_socket(sock); ++ return 0; ++} ++#endif ++ + /** Register a new IGMP membership. On socket close, the membership is dropped automatically. + * + * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). +@@ -4357,8 +4378,11 @@ lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr + if (!sock) { + return 0; + } +- ++#if GAZELLE_ENABLE ++ i = s; ++#else + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { ++#endif + if (socket_ipv4_multicast_memberships[i].sock == NULL) { + socket_ipv4_multicast_memberships[i].sock = sock; + ip4_addr_copy(socket_ipv4_multicast_memberships[i].if_addr, *if_addr); +@@ -4366,7 +4390,9 @@ lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr + done_socket(sock); + return 1; + } ++#if !GAZELLE_ENABLE + } ++#endif + done_socket(sock); + return 0; + } +@@ -4386,16 +4412,24 @@ lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_ad + return; + } + ++#if GAZELLE_ENABLE ++ i = s; ++#else + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { ++#endif + if ((socket_ipv4_multicast_memberships[i].sock == sock) && + ip4_addr_eq(&socket_ipv4_multicast_memberships[i].if_addr, if_addr) && + ip4_addr_eq(&socket_ipv4_multicast_memberships[i].multi_addr, multi_addr)) { + socket_ipv4_multicast_memberships[i].sock = NULL; + ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); + ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); ++#if !GAZELLE_ENABLE + break; ++#endif + } ++#if !GAZELLE_ENABLE + } ++#endif + done_socket(sock); + } + +@@ -4412,8 +4446,11 @@ lwip_socket_drop_registered_memberships(int s) + if (!sock) { + return; + } +- ++#if GAZELLE_ENABLE ++ i = s; ++#else + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { ++#endif + if (socket_ipv4_multicast_memberships[i].sock == sock) { + ip_addr_t multi_addr, if_addr; + ip_addr_copy_from_ip4(multi_addr, socket_ipv4_multicast_memberships[i].multi_addr); +@@ -4424,7 +4461,9 @@ lwip_socket_drop_registered_memberships(int s) + + netconn_join_leave_group(sock->conn, &multi_addr, &if_addr, NETCONN_LEAVE); + } ++#if !GAZELLE_ENABLE + } ++#endif + done_socket(sock); + } + #endif /* LWIP_IGMP */ +diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h +index 4466f11..296d4eb 100644 +--- a/src/include/lwip/sockets.h ++++ b/src/include/lwip/sockets.h +@@ -361,6 +361,7 @@ struct linger { + #if GAZELLE_UDP_ENABLE + #define IP_ADD_MEMBERSHIP 35 + #define IP_DROP_MEMBERSHIP 36 ++int lwip_socket_get_multi_memberships(int s, ip4_addr_t *if_addr, ip4_addr_t *multi_addr); + #else + /* + * Options and types related to multicast membership +-- +2.33.0 + diff --git a/0119-support-igmpv3.patch b/0119-support-igmpv3.patch new file mode 100644 index 0000000..f1d839e --- /dev/null +++ b/0119-support-igmpv3.patch @@ -0,0 +1,2499 @@ +diff -Nur lwip-2.2.0init/src/api/api_msg.c lwip-2.2.0/src/api/api_msg.c +--- lwip-2.2.0init/src/api/api_msg.c 2024-04-02 19:14:40.959584000 +0800 ++++ lwip-2.2.0/src/api/api_msg.c 2024-04-02 19:15:03.866584000 +0800 +@@ -192,9 +192,19 @@ + + buf->p = q; + buf->ptr = q; +- ip_addr_copy(buf->addr, *ip_current_src_addr()); ++ ip_addr_copy(buf->addr, *addr); + buf->port = pcb->protocol; + ++#if LWIP_NETBUF_RECVINFO ++ if (conn->flags & NETCONN_FLAG_PKTINFO) { ++ buf->flags = NETBUF_FLAG_DESTADDR; ++ /* If we use mroute this packet maybe a mroute fake packet so we must get ipv4/ipv6 header */ ++ if (IP_IS_V4(addr)) { ++ struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; ++ ip_addr_copy_from_ip4(buf->toaddr, iphdr->dest); ++ } else {} ++#endif /* LWIP_NETBUF_RECVINFO */ ++ + len = q->tot_len; + if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); +@@ -2071,6 +2081,7 @@ + + msg->err = ERR_CONN; + if (msg->conn->pcb.tcp != NULL) { ++#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { + #if LWIP_UDP + #if LWIP_IPV6 && LWIP_IPV6_MLD +@@ -2082,25 +2093,33 @@ + msg->err = mld6_leavegroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), + ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); + } +- } else ++ } else { + #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ +- { +-#if LWIP_IGMP +- if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { +- msg->err = igmp_joingroup(ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)), +- ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); +- } else { +- msg->err = igmp_leavegroup(ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)), +- ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); +- } +-#endif /* LWIP_IGMP */ ++#if LWIP_IGMP ++ if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { ++ msg->err = mcast_join_group(&msg->conn->pcb.udp->ipmc, API_EXPR_REF(msg->msg.jl.netif_addr), API_EXPR_REF(msg->msg.jl.multiaddr), NULL); ++ } else { ++ msg->err = mcast_leave_group(&msg->conn->pcb.udp->ipmc, API_EXPR_REF(msg->msg.jl.netif_addr), API_EXPR_REF(msg->msg.jl.multiaddr), NULL); ++ } ++#endif /*LWIP_IGMP*/ + } ++#else ++ msg->err = ERR_VAL; + #endif /* LWIP_UDP */ +-#if (LWIP_TCP || LWIP_RAW) ++ } else if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_RAW) { ++#if LWIP_RAW ++ if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { ++ msg->err = mcast_join_group(&msg->conn->pcb.raw->ipmc, API_EXPR_REF(msg->msg.jl.netif_addr), API_EXPR_REF(msg->msg.jl.multiaddr), NULL); ++ } else { ++ msg->err = mcast_leave_group(&msg->conn->pcb.raw->ipmc, API_EXPR_REF(msg->msg.jl.netif_addr), API_EXPR_REF(msg->msg.jl.multiaddr), NULL); ++ } ++#else ++ msg->err = ERR_VAL; ++#endif /* LWIP_RAW */ + } else { + msg->err = ERR_VAL; +-#endif /* (LWIP_TCP || LWIP_RAW) */ + } ++#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ + } + TCPIP_APIMSG_ACK(msg); + } +@@ -2124,6 +2143,7 @@ + + msg->err = ERR_CONN; + if (msg->conn->pcb.tcp != NULL) { ++#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { + #if LWIP_UDP + #if LWIP_IPV6 && LWIP_IPV6_MLD +@@ -2137,23 +2157,32 @@ + } + } else + #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ +- { +-#if LWIP_IGMP +- if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { +- msg->err = igmp_joingroup_netif(netif, +- ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); +- } else { +- msg->err = igmp_leavegroup_netif(netif, +- ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); +- } +-#endif /* LWIP_IGMP */ ++ { ++#if LWIP_IGMP ++ if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { ++ msg->err = mcast_join_netif(&msg->conn->pcb.udp->ipmc, netif, API_EXPR_REF(msg->msg.jl.multiaddr), NULL); ++ } else { ++ msg->err = mcast_leave_netif(&msg->conn->pcb.udp->ipmc, netif, API_EXPR_REF(msg->msg.jl.multiaddr), NULL); + } ++#endif /*LWIP_IGMP*/ ++#else ++ msg->err = ERR_VAL; + #endif /* LWIP_UDP */ +-#if (LWIP_TCP || LWIP_RAW) ++ } ++ } else if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_RAW) { ++#if LWIP_RAW ++ if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { ++ msg->err = mcast_join_netif(&msg->conn->pcb.raw->ipmc, netif, API_EXPR_REF(msg->msg.jl.multiaddr), NULL); ++ } else { ++ msg->err = mcast_leave_netif(&msg->conn->pcb.raw->ipmc, netif, API_EXPR_REF(msg->msg.jl.multiaddr), NULL); ++ } ++#else ++ msg->err = ERR_VAL; ++#endif /* LWIP_RAW */ + } else { + msg->err = ERR_VAL; +-#endif /* (LWIP_TCP || LWIP_RAW) */ + } ++#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ + } + + done: +diff -Nur lwip-2.2.0init/src/api/sockets.c lwip-2.2.0/src/api/sockets.c +--- lwip-2.2.0init/src/api/sockets.c 2024-04-02 19:14:40.959584000 +0800 ++++ lwip-2.2.0/src/api/sockets.c 2024-04-02 19:15:03.867584000 +0800 +@@ -293,16 +293,16 @@ + struct lwip_socket_multicast_pair { + /** the socket */ + struct lwip_sock *sock; +- /** the interface address */ +- ip4_addr_t if_addr; ++ /** the interface index */ ++ u8_t if_idx; + /** the group address */ + ip4_addr_t multi_addr; + }; + + static struct lwip_socket_multicast_pair socket_ipv4_multicast_memberships[LWIP_SOCKET_MAX_MEMBERSHIPS]; + +-static int lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr); +-static void lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr); ++static int lwip_socket_register_membership(int s, unsigned int if_idx, const ip4_addr_t *multi_addr); ++static void lwip_socket_unregister_membership(int s, unsigned int if_idx, const ip4_addr_t *multi_addr); + static void lwip_socket_drop_registered_memberships(int s); + #endif /* LWIP_IGMP */ + +@@ -3841,32 +3841,24 @@ + #endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP */ + #if LWIP_IGMP + case IP_ADD_MEMBERSHIP: +- case IP_DROP_MEMBERSHIP: { ++ case IP_DROP_MEMBERSHIP: + /* If this is a TCP or a RAW socket, ignore these options. */ +- err_t igmp_err; +- const struct ip_mreq *imr = (const struct ip_mreq *)optval; +- ip4_addr_t if_addr; +- ip4_addr_t multi_addr; +- LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ip_mreq, NETCONN_UDP); +- inet_addr_to_ip4addr(&if_addr, &imr->imr_interface); +- inet_addr_to_ip4addr(&multi_addr, &imr->imr_multiaddr); +- if (optname == IP_ADD_MEMBERSHIP) { +- if (!lwip_socket_register_membership(s, &if_addr, &multi_addr)) { +- /* cannot track membership (out of memory) */ +- err = ENOMEM; +- igmp_err = ERR_OK; +- } else { +- igmp_err = igmp_joingroup(&if_addr, &multi_addr); +- } +- } else { +- igmp_err = igmp_leavegroup(&if_addr, &multi_addr); +- lwip_socket_unregister_membership(s, &if_addr, &multi_addr); +- } +- if (igmp_err != ERR_OK) { +- err = EADDRNOTAVAIL; +- } +- } +- break; ++ LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, struct ip_mreq); ++#if LWIP_UDP ++ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_UDP) { ++ err = mcast_sock_add_drop_membership(s, &sock->conn->pcb.udp->ipmc, optname, (const struct ip_mreq *)optval); ++ } else ++#endif /* LWIP_UDP */ ++#if LWIP_RAW ++ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_RAW) { ++ err = mcast_sock_add_drop_membership(s, &sock->conn->pcb.raw->ipmc, optname, (const struct ip_mreq *)optval); ++ } else ++#endif /* LWIP_RAW */ ++ { ++ done_socket(sock); ++ return ENOPROTOOPT; ++ } ++ break; + #endif /* LWIP_IGMP */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", +@@ -4343,7 +4335,7 @@ + + #if LWIP_IGMP + #if GAZELLE_ENABLE +-int lwip_socket_get_multi_memberships(int s, ip4_addr_t *if_addr, ip4_addr_t *multi_addr) ++int lwip_socket_get_multi_memberships(int s, unsigned int if_idx, ip4_addr_t *multi_addr) + { + struct lwip_sock *sock = get_socket(s); + +@@ -4352,7 +4344,7 @@ + } + + if (socket_ipv4_multicast_memberships[s].sock == sock) { +- ip4_addr_copy(*if_addr, socket_ipv4_multicast_memberships[s].if_addr); ++ if_idx = socket_ipv4_multicast_memberships[s].if_idx; + ip4_addr_copy(*multi_addr, socket_ipv4_multicast_memberships[s].multi_addr); + done_socket(sock); + return 1; +@@ -4370,7 +4362,7 @@ + * @return 1 on success, 0 on failure + */ + static int +-lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr) ++lwip_socket_register_membership(int s, unsigned int if_idx, const ip4_addr_t *multi_addr) + { + struct lwip_sock *sock = get_socket(s); + int i; +@@ -4378,6 +4370,8 @@ + if (!sock) { + return 0; + } ++ SYS_ARCH_DECL_PROTECT(lev); ++ SYS_ARCH_PROTECT(lev); + #if GAZELLE_ENABLE + i = s; + #else +@@ -4385,7 +4379,7 @@ + #endif + if (socket_ipv4_multicast_memberships[i].sock == NULL) { + socket_ipv4_multicast_memberships[i].sock = sock; +- ip4_addr_copy(socket_ipv4_multicast_memberships[i].if_addr, *if_addr); ++ socket_ipv4_multicast_memberships[i].if_idx = if_idx; + ip4_addr_copy(socket_ipv4_multicast_memberships[i].multi_addr, *multi_addr); + done_socket(sock); + return 1; +@@ -4393,6 +4387,7 @@ + #if !GAZELLE_ENABLE + } + #endif ++ SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + return 0; + } +@@ -4403,7 +4398,7 @@ + * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). + */ + static void +-lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr) ++lwip_socket_unregister_membership(int s, unsigned int if_idx, const ip4_addr_t *multi_addr) + { + struct lwip_sock *sock = get_socket(s); + int i; +@@ -4411,17 +4406,18 @@ + if (!sock) { + return; + } +- ++ SYS_ARCH_DECL_PROTECT(lev); ++ SYS_ARCH_PROTECT(lev); + #if GAZELLE_ENABLE + i = s; + #else + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + #endif + if ((socket_ipv4_multicast_memberships[i].sock == sock) && +- ip4_addr_eq(&socket_ipv4_multicast_memberships[i].if_addr, if_addr) && +- ip4_addr_eq(&socket_ipv4_multicast_memberships[i].multi_addr, multi_addr)) { ++ (socket_ipv4_multicast_memberships[i].if_idx == if_idx) && ++ ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].multi_addr, multi_addr)) { + socket_ipv4_multicast_memberships[i].sock = NULL; +- ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); ++ socket_ipv4_multicast_memberships[i].if_idx = NETIF_NO_INDEX; + ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); + #if !GAZELLE_ENABLE + break; +@@ -4430,6 +4426,7 @@ + #if !GAZELLE_ENABLE + } + #endif ++ SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + } + +@@ -4446,24 +4443,29 @@ + if (!sock) { + return; + } ++ SYS_ARCH_DECL_PROTECT(lev); ++ SYS_ARCH_PROTECT(lev); + #if GAZELLE_ENABLE + i = s; + #else + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + #endif + if (socket_ipv4_multicast_memberships[i].sock == sock) { +- ip_addr_t multi_addr, if_addr; ++ ip_addr_t multi_addr; ++ u8_t if_idx; + ip_addr_copy_from_ip4(multi_addr, socket_ipv4_multicast_memberships[i].multi_addr); +- ip_addr_copy_from_ip4(if_addr, socket_ipv4_multicast_memberships[i].if_addr); ++ if_idx = socket_ipv4_multicast_memberships[i].if_idx; ++ ++ socket_ipv4_multicast_memberships[i].if_idx = NETIF_NO_INDEX; + socket_ipv4_multicast_memberships[i].sock = NULL; +- ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); + ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); + +- netconn_join_leave_group(sock->conn, &multi_addr, &if_addr, NETCONN_LEAVE); ++ netconn_join_leave_group_netif(sock->conn, &multi_addr, if_idx, NETCONN_LEAVE); + } + #if !GAZELLE_ENABLE + } + #endif ++ SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + } + #endif /* LWIP_IGMP */ +@@ -4484,8 +4486,17 @@ + if (!sock) { + return 0; + } +- ++ ++ SYS_ARCH_DECL_PROTECT(lev); ++ SYS_ARCH_PROTECT(lev); + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { ++ if ((socket_ipv6_multicast_memberships[i].sock == sock) && ++ (socket_ipv6_multicast_memberships[i].if_idx == if_idx) && ++ ip6_addr_cmp(&socket_ipv6_multicast_memberships[i].multi_addr, multi_addr)) { ++ done_socket(sock); ++ return 1; ++ } ++ + if (socket_ipv6_multicast_memberships[i].sock == NULL) { + socket_ipv6_multicast_memberships[i].sock = sock; + socket_ipv6_multicast_memberships[i].if_idx = (u8_t)if_idx; +@@ -4494,6 +4505,7 @@ + return 1; + } + } ++ SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + return 0; + } +@@ -4513,16 +4525,19 @@ + return; + } + ++ SYS_ARCH_DECL_PROTECT(lev); ++ SYS_ARCH_PROTECT(lev); + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if ((socket_ipv6_multicast_memberships[i].sock == sock) && + (socket_ipv6_multicast_memberships[i].if_idx == if_idx) && +- ip6_addr_eq(&socket_ipv6_multicast_memberships[i].multi_addr, multi_addr)) { ++ ip6_addr_cmp(&socket_ipv6_multicast_memberships[i].multi_addr, multi_addr)) { + socket_ipv6_multicast_memberships[i].sock = NULL; + socket_ipv6_multicast_memberships[i].if_idx = NETIF_NO_INDEX; + ip6_addr_set_zero(&socket_ipv6_multicast_memberships[i].multi_addr); + break; + } + } ++ SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + } + +@@ -4539,7 +4554,8 @@ + if (!sock) { + return; + } +- ++ SYS_ARCH_DECL_PROTECT(lev); ++ SYS_ARCH_PROTECT(lev); + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if (socket_ipv6_multicast_memberships[i].sock == sock) { + ip_addr_t multi_addr; +@@ -4555,10 +4571,159 @@ + netconn_join_leave_group_netif(sock->conn, &multi_addr, if_idx, NETCONN_LEAVE); + } + } ++ SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + } + #endif /* LWIP_IPV6_MLD */ + ++/** Remove multicast filter when pcb remove ++ * ++ * @param ipmc multicast filter control block ++ */ ++void ++mcast_pcb_remove(struct ip_mc *ipmc) ++{ ++#if LWIP_IPV4 && LWIP_IGMP ++ { ++ struct ip4_mc *mc, *next; ++ ++ mc = ipmc->mc4; ++ while (mc) { ++ next = mc->next; ++ mcast_ip4_mc_src_remove(mc->src); ++ igmp_leavegroup(&mc->if_addr, &mc->multi_addr); ++ mem_free(mc); ++ mc = next; ++ } ++ } ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++} ++ ++/** Common code to see if the current input multicast packet matches the pcb ++ * (current input packet is accessed via ip(4/6)_current_* macros) ++ * ++ * @param ipmc multicast filter control block ++ * @param inp network interface on which the datagram was received (only used for IPv4) ++ * @return 1 on match, 0 otherwise ++ */ ++u8_t ++mcast_input_local_match(struct ip_mc *ipmc, struct netif *inp) ++{ ++#if LWIP_IPV4 && LWIP_IGMP ++ if (!ip_current_is_v6()) { ++ struct igmp_src *src; ++ struct ip4_mc *mc; ++ ip4_addr_t *multi_addr = ip4_current_dest_addr(); ++ ip4_addr_t *src_addr = ip4_current_src_addr(); ++ ++ IP4_MC_FOREACH(ipmc, mc) { ++ if (ip4_addr_cmp(&mc->if_addr, netif_ip4_addr(inp)) && ++ ip4_addr_cmp(&mc->multi_addr, multi_addr)) { ++ if (mc->fmode == MCAST_EXCLUDE) { ++ IP4_MC_SRC_FOREACH(mc, src) { ++ if (ip4_addr_cmp(&src->src_addr, src_addr)) { ++ return 0; ++ } ++ } ++ return 1; /* MCAST_EXCLUDE src_addr must not in src list */ ++ ++ } else { /* MCAST_INCLUDE */ ++ IP4_MC_SRC_FOREACH(mc, src) { ++ if (ip4_addr_cmp(&src->src_addr, src_addr)) { ++ return 1; ++ } ++ } ++ return 0; /* MCAST_INCLUDE src_addr must in src list */ ++ } ++ } ++ } ++ } else {} ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++ return 0; ++} ++ ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++/** ++ * setsockopt() IP_ADD_MEMBERSHIP / IP_DROP_MEMBERSHIP command ++ */ ++int ++mcast_sock_add_drop_membership(int s, struct ip_mc *ipmc, int optname, const struct ip_mreq *imr) ++{ ++ struct netif *netif; ++ ip_addr_t if_addr; ++ ip_addr_t multi_addr; ++ err_t err; ++ u8_t if_idx; ++ ++ inet_addr_to_ip4addr(ip_2_ip4(&if_addr), &imr->imr_interface); ++ inet_addr_to_ip4addr(ip_2_ip4(&multi_addr), &imr->imr_multiaddr); ++ IP_SET_TYPE_VAL(if_addr, IPADDR_TYPE_V4); ++ IP_SET_TYPE_VAL(multi_addr, IPADDR_TYPE_V4); ++ ++ if (!ip4_addr_ismulticast(ip_2_ip4(&multi_addr))) { ++ return EADDRNOTAVAIL; ++ } ++ ++ if (ip4_addr_isany(ip_2_ip4(&if_addr))) { /* To all network interface */ ++ if (optname == IP_ADD_MEMBERSHIP) { ++ NETIF_FOREACH(netif) { ++ if_idx = netif_get_index(netif); ++ if (!lwip_socket_register_membership(s, if_idx, ip_2_ip4(&multi_addr))) { ++ /* cannot track membership (out of memory) */ ++ err = ENOMEM; ++ goto out; ++ } ++ } ++ ++ err = mcast_join_group(ipmc, &if_addr, &multi_addr, NULL); ++ } else { ++ err = mcast_leave_group(ipmc, &if_addr, &multi_addr, NULL); ++ NETIF_FOREACH(netif) { ++ if_idx = netif_get_index(netif); ++ lwip_socket_unregister_membership(s, if_idx, ip_2_ip4(&multi_addr)); ++ } ++ } ++ ++ } else { /* To specified network interface */ ++ if (!(ip_2_ip4(&if_addr)->addr & PP_HTONL(IP_CLASSA_NET))) { /* IS a BSD style index ? */ ++ u8_t idx = (u8_t)PP_NTOHL(ip_2_ip4(&if_addr)->addr); ++ netif = netif_get_by_index(idx); ++ if (netif == NULL) { ++ return ENXIO; ++ } ++ *ip_2_ip4(&if_addr) = *netif_ip4_addr(netif); ++ ++ } else { ++ NETIF_FOREACH(netif) { ++ if (ip4_addr_cmp(ip_2_ip4(&if_addr), netif_ip4_addr(netif))) { ++ break; ++ } ++ } ++ if (netif == NULL) { ++ return ENXIO; ++ } ++ } ++ ++ if (optname == IP_ADD_MEMBERSHIP) { ++ if_idx = netif_get_index(netif); ++ if (!lwip_socket_register_membership(s, if_idx, ip_2_ip4(&multi_addr))) { ++ /* cannot track membership (out of memory) */ ++ err = ENOMEM; ++ goto out; ++ } ++ err = mcast_join_netif(ipmc, netif, &multi_addr, NULL); ++ } else { ++ err = mcast_leave_netif(ipmc, netif, &multi_addr, NULL); ++ if_idx = netif_get_index(netif); ++ lwip_socket_unregister_membership(s, if_idx, ip_2_ip4(&multi_addr)); ++ } ++ } ++ ++out: ++ return (u8_t)err_to_errno(err); ++} ++#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD)*/ ++ + #if GAZELLE_ENABLE + void lwip_sock_init(void) + { +diff -Nur lwip-2.2.0init/src/core/dir.mk lwip-2.2.0/src/core/dir.mk +--- lwip-2.2.0init/src/core/dir.mk 2024-04-02 19:14:40.969584000 +0800 ++++ lwip-2.2.0/src/core/dir.mk 2024-04-02 19:15:03.867584000 +0800 +@@ -3,6 +3,6 @@ + ipv4/icmp.c ipv4/ip4_addr.c ipv4/ip4_frag.c ipv4/etharp.c \ + ipv4/ip4.c ipv4/igmp.c ipv6/icmp6.c ipv6/ip6_addr.c ipv6/ip6_frag.c \ + ipv6/ethip6.c ipv6/ip6.c ipv6/dhcp6.c ipv6/inet6.c \ +- ipv6/mld6.c ipv6/nd6.c ++ ipv6/mld6.c ipv6/nd6.c mcast.c + + $(eval $(call register_dir, core, $(SRC))) +diff -Nur lwip-2.2.0init/src/core/ipv4/igmp.c lwip-2.2.0/src/core/ipv4/igmp.c +--- lwip-2.2.0init/src/core/ipv4/igmp.c 2024-04-02 19:14:40.968584000 +0800 ++++ lwip-2.2.0/src/core/ipv4/igmp.c 2024-04-02 19:15:03.867584000 +0800 +@@ -93,6 +93,7 @@ + #include "lwip/netif.h" + #include "lwip/stats.h" + #include "lwip/prot/igmp.h" ++#include "lwip/sockets.h" + + #include + +@@ -104,9 +105,21 @@ + static err_t igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif); + static void igmp_send(struct netif *netif, struct igmp_group *group, u8_t type); + ++#if LWIP_IGMP_V3 ++static void igmp_v3_timeout(struct netif *netif, struct igmp_group *group); ++static void igmp_v3_start_timer(struct igmp_group *group, u8_t max_time); ++static void igmp_v3_delaying_member(struct igmp_group *group, u8_t maxresp); ++static void igmp_v3_send(struct netif *netif, struct igmp_group *group, u8_t type); ++static void igmp_v3_send_allgroups(struct netif *netif); ++#endif /* LWIP_IGMP_V3 */ ++ + static ip4_addr_t allsystems; + static ip4_addr_t allrouters; + ++#if LWIP_IGMP_V3 ++static ip4_addr_t v3_routers; ++#endif /* LWIP_IGMP_V3 */ ++ + /** + * Initialize the IGMP module + */ +@@ -117,6 +130,10 @@ + + IP4_ADDR(&allsystems, 224, 0, 0, 1); + IP4_ADDR(&allrouters, 224, 0, 0, 2); ++ ++#if LWIP_IGMP_V3 ++ IP4_ADDR(&v3_routers, 224, 0, 0, 22); ++#endif /* LWIP_IGMP_V3 */ + } + + /** +@@ -136,6 +153,9 @@ + if (group != NULL) { + group->group_state = IGMP_GROUP_IDLE_MEMBER; + group->use++; ++#if LWIP_IGMP_V3 ++ group->v3_group_state = IGMP_GROUP_IDLE_MEMBER; ++#endif /* LWIP_IGMP_V3 */ + + /* Allow the igmp messages at the MAC level */ + if (netif->igmp_mac_filter != NULL) { +@@ -204,6 +224,15 @@ + igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR); + group = group->next; + } ++ ++#if LWIP_IGMP_V3 ++ group = netif_igmp_data(netif); ++ ++ if (group) { ++ /* We use first group to determine report all groups */ ++ igmp_v3_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR); ++ } ++#endif /* LWIP_IGMP_V3 */ + } + + /** +@@ -261,6 +290,12 @@ + group->group_state = IGMP_GROUP_NON_MEMBER; + group->last_reporter_flag = 0; + group->use = 0; ++#if LWIP_IGMP_V3 ++ group->v3_fmode = IGMP_FMODE_INIT; /* Non mode with init-stat */ ++ group->v3_timer = 0; /* Not running */ ++ group->v3_group_state = IGMP_GROUP_NON_MEMBER; ++ group->v3_last_reporter_flag = 0; ++#endif /* LWIP_IGMP_V3 */ + + /* Ensure allsystems group is always first in list */ + if (list_head == NULL) { +@@ -365,6 +400,71 @@ + /* NOW ACT ON THE INCOMING MESSAGE TYPE... */ + switch (igmp->igmp_msgtype) { + case IGMP_MEMB_QUERY: ++#if LWIP_IGMP_V3 ++ if (p->len >= IGMP_V3_MINLEN) { /* this is a igmp v3 query packet */ ++ struct igmp_v3_query *igmp_v3 = (struct igmp_v3_query *)p->payload; ++ ++ if ((ip4_addr_cmp(dest, &allsystems)) && ip4_addr_isany(&igmp_v3->igmp_v3_group_address)) { ++ /* THIS IS THE GENERAL QUERY */ ++ groupref = netif_igmp_data(inp); ++ ++ if (groupref) { ++ /* We use first group to determine report all groups */ ++ igmp_v3_delaying_member(groupref, igmp_v3->igmp_v3_maxresp); ++ } ++ ++ } else { ++ /* IGMP_MEMB_QUERY to a specific group ? */ ++ if (!ip4_addr_isany(&igmp_v3->igmp_v3_group_address)) { ++ u16_t src_cnt = PP_NTOHS(igmp_v3->igmp_v3_srccnt); ++ u16_t src_buf_size = src_cnt << 2; ++ u8_t need_free; ++ ip4_addr_p_t *src_buf; ++ ++ if (p->tot_len < (IGMP_V3_QUERY_HLEN + src_buf_size)) { ++ /* packet len error */ ++ pbuf_free(p); ++ IGMP_STATS_INC(igmp.lenerr); ++ LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n")); ++ return; ++ } ++ ++ if (src_cnt) { /* Seach interest */ ++ if (p->len < (IGMP_V3_QUERY_HLEN + src_buf_size)) { /* Unfortunately! the source address memory is not contiguous */ ++ src_buf = (ip4_addr_p_t *)mem_malloc(src_buf_size); ++ if (src_buf == NULL) { ++ pbuf_free(p); ++ IGMP_STATS_INC(igmp.memerr); ++ LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: not enough memory for igmp_input\n")); ++ return; ++ } ++ need_free = 1; ++ pbuf_copy_partial(p, src_buf, src_buf_size, IGMP_V3_QUERY_HLEN); ++ ++ } else { ++ need_free = 0; ++ src_buf = (ip4_addr_p_t *)((u8_t *)p->payload + IGMP_V3_QUERY_HLEN); ++ } ++ ++ LWIP_ASSERT("igmp_v3_query packet source address array not aligned!", !((mem_ptr_t)src_buf & 0x3)); ++ ip4_addr_t igmp_v3_group_address; ++ memcpy(&igmp_v3_group_address, &igmp_v3->igmp_v3_group_address, sizeof(igmp_v3_group_address)); ++ if (mcast_ip4_filter_interest(inp, (const ip4_addr_t *)&igmp_v3_group_address, src_buf, src_cnt)) { ++ /* We interest! */ ++ igmp_v3_delaying_member(group, igmp_v3->igmp_v3_maxresp); ++ } ++ ++ if (need_free) { ++ mem_free(src_buf); ++ } ++ ++ } else { /* Report! */ ++ igmp_v3_delaying_member(group, igmp_v3->igmp_v3_maxresp); ++ } ++ } ++ } ++ } ++#endif /* LWIP_IGMP_V3 */ + /* IGMP_MEMB_QUERY to the "all systems" address ? */ + if ((ip4_addr_eq(dest, &allsystems)) && ip4_addr_isany(&igmp->igmp_group_address)) { + /* THIS IS THE GENERAL QUERY */ +@@ -523,6 +623,16 @@ + + /* Need to work out where this timer comes from */ + group->group_state = IGMP_GROUP_DELAYING_MEMBER; ++ ++ ++#if LWIP_IGMP_V3 ++ igmp_v3_send(netif, group, IGMP_V3_MEMB_REPORT); ++ ++ igmp_v3_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR); ++ ++ /* Need to work out where this timer comes from */ ++ group->v3_group_state = IGMP_GROUP_DELAYING_MEMBER; ++#endif /* LWIP_IGMP_V3 */ + } + /* Increment group use */ + group->use++; +@@ -612,6 +722,13 @@ + igmp_send(netif, group, IGMP_LEAVE_GROUP); + } + ++#if LWIP_IGMP_V3 ++ /* If we are the last reporter for this group */ ++ if (group->v3_last_reporter_flag) { ++ igmp_v3_send(netif, group, IGMP_LEAVE_GROUP); ++ } ++#endif /* LWIP_IGMP_V3 */ ++ + /* Disable the group at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: igmp_mac_filter(DEL ")); +@@ -654,6 +771,19 @@ + } + group = group->next; + } ++ ++#if LWIP_IGMP_V3 ++ group = netif_igmp_data(netif); ++ while (group != NULL) { ++ if (group->v3_timer > 0) { ++ group->v3_timer--; ++ if (group->v3_timer == 0) { ++ igmp_v3_timeout(netif, group); ++ } ++ } ++ group = group->next; ++ } ++#endif /* LWIP_IGMP_V3 */ + } + } + +@@ -681,6 +811,36 @@ + } + } + ++#if LWIP_IGMP_V3 ++/** ++ * Called if a timeout for one group is reached. ++ * Sends a report for this group. ++ * ++ * @param group an igmp_group for which a timeout is reached ++ */ ++static void ++igmp_v3_timeout(struct netif *netif, struct igmp_group *group) ++{ ++ /* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group ++ (if it is the allsystems group to all groups) */ ++ if (group->v3_group_state == IGMP_GROUP_DELAYING_MEMBER) { ++ group->group_state = IGMP_GROUP_IDLE_MEMBER; ++ if (ip4_addr_cmp(&(group->group_address), &allsystems)) { ++ LWIP_DEBUGF(IGMP_DEBUG, ("igmp_v3_timeout: report all membership\n")); ++ IGMP_STATS_INC(igmp.tx_report); ++ igmp_v3_send_allgroups(netif); ++ ++ } else { ++ LWIP_DEBUGF(IGMP_DEBUG, ("igmp_v3_timeout: report membership for group with address ")); ++ ip4_addr_debug_print(IGMP_DEBUG, &(group->group_address)); ++ LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)netif)); ++ IGMP_STATS_INC(igmp.tx_report); ++ igmp_v3_send(netif, group, IGMP_V3_MEMB_REPORT); ++ } ++ } ++} ++#endif /* LWIP_IGMP_V3 */ ++ + /** + * Start a timer for an igmp group + * +@@ -703,6 +863,51 @@ + } + } + ++#if LWIP_IGMP_V3 ++/** ++ * Start a timer for an igmp group ++ * ++ * @param group the igmp_group for which to start a timer ++ * @param max_time the time in multiples of IGMP_TMR_INTERVAL (decrease with ++ * every call to igmp_tmr()) ++ */ ++static void ++igmp_v3_start_timer(struct igmp_group *group, u8_t max_time) ++{ ++ /* ++ * If Max Resp Code < 128, Max Resp Time = Max Resp Code ++ * ++ * If Max Resp Code >= 128, Max Resp Code represents a floating-point ++ * value as follows: ++ * ++ * 0 1 2 3 4 5 6 7 ++ * +-+-+-+-+-+-+-+-+ ++ * |1| exp | mant | ++ * +-+-+-+-+-+-+-+-+ ++ * ++ * Max Resp Time = (mant | 0x10) << (exp + 3) ++ */ ++ u16_t delay; ++ ++ if (max_time < 128) { ++ delay = max_time; ++ } else { ++ delay = ((max_time & 0xf) | 0x10) << (((max_time >> 4) & 7) + 3); ++ } ++ ++#ifdef LWIP_RAND ++ group->v3_timer = (u16_t)(delay > 2 ? (LWIP_RAND() % delay) : 1); ++#else /* LWIP_RAND */ ++ /* ATTENTION: use this only if absolutely necessary! */ ++ group->v3_timer = delay / 2; ++#endif /* LWIP_RAND */ ++ ++ if (group->v3_timer == 0) { ++ group->v3_timer = 1; ++ } ++} ++#endif /* LWIP_IGMP_V3 */ ++ + /** + * Delaying membership report for a group if necessary + * +@@ -721,6 +926,33 @@ + } + + ++#if LWIP_IGMP_V3 ++/** ++ * Delaying membership report for a group if necessary ++ * ++ * @param group the igmp_group for which "delaying" membership report ++ * @param maxresp query delay ++ */ ++static void ++igmp_v3_delaying_member(struct igmp_group *group, u8_t maxresp) ++{ ++ u16_t delay; ++ ++ if (maxresp < 128) { ++ delay = maxresp; ++ } else { ++ delay = ((maxresp & 0xf) | 0x10) << (((maxresp >> 4) & 7) + 3); ++ } ++ ++ if ((group->v3_group_state == IGMP_GROUP_IDLE_MEMBER) || ++ ((group->v3_group_state == IGMP_GROUP_DELAYING_MEMBER) && ++ ((group->v3_timer == 0) || (delay < group->timer)))) { ++ igmp_v3_start_timer(group, maxresp); ++ group->v3_group_state = IGMP_GROUP_DELAYING_MEMBER; ++ } ++} ++#endif /* LWIP_IGMP_V3 */ ++ + /** + * Sends an IP packet on a network interface. This function constructs the IP header + * and calculates the IP header checksum. If the source IP address is NULL, +@@ -798,4 +1030,220 @@ + } + } + ++#if LWIP_IGMP_V3 ++/** ++ * Build a igmp v3 record to a specific group. ++ * ++ * @param rec record to build ++ * @param group the group to which to send the packet ++ * @param fmode filter mode ++ * @param src_array source addr array ++ * @param src_cnt source addr cnt ++ */ ++static void ++igmp_v3_build_record(struct igmp_v3_record *rec, struct igmp_group *group, u8_t fmode, ip4_addr_p_t *src_array, u32_t src_cnt) ++{ ++ ip4_addr_p_t *src_copy; ++ ++ if (fmode == MCAST_EXCLUDE) { ++ if (group->v3_fmode != MCAST_EXCLUDE) { ++ group->v3_fmode = MCAST_EXCLUDE; ++ rec->igmp_v3_rc_type = IGMP_V3_REC_TO_EX; ++ } else { ++ rec->igmp_v3_rc_type = IGMP_V3_REC_IS_EX; ++ } ++ ++ } else { ++ if (group->v3_fmode != MCAST_INCLUDE) { ++ group->v3_fmode = MCAST_INCLUDE; ++ rec->igmp_v3_rc_type = IGMP_V3_REC_TO_IN; ++ } else { ++ rec->igmp_v3_rc_type = IGMP_V3_REC_IS_IN; ++ } ++ } ++ ++ rec->igmp_v3_rc_auxlen = 0; ++ rec->igmp_v3_rc_srccnt = PP_HTONS(src_cnt); ++ ip4_addr_set(&rec->igmp_v3_rc_group_address, &group->group_address); ++ ++ if (src_cnt) { ++ src_copy = (ip4_addr_p_t *)(rec + 1); ++ MEMCPY(src_copy, src_array, (src_cnt << 2)); ++ } ++} ++ ++/** ++ * Send an igmp v3 packet to a specific group. ++ * ++ * @param group the group to which to send the packet ++ * @param type the type of igmp packet to send ++ */ ++static void ++igmp_v3_send(struct netif *netif, struct igmp_group *group, u8_t type) ++{ ++ struct igmp_v3_report *rep; ++ struct igmp_v3_record *rec; ++ ip4_addr_t src; ++ struct pbuf *p; ++ ++ ip4_addr_copy(src, *netif_ip4_addr(netif)); ++ ++ if (type == IGMP_LEAVE_GROUP) { /* Leave from a group */ ++ p = pbuf_alloc(PBUF_TRANSPORT, IGMP_V3_REPORT_HLEN + IGMP_V3_RECORD_LEN(0), PBUF_RAM); ++ if (p == NULL) { ++ LWIP_DEBUGF(IGMP_DEBUG, ("igmp_v3_send: not enough memory for igmp_v3_send\n")); ++ IGMP_STATS_INC(igmp.memerr); ++ return; ++ } ++ ++ rep = (struct igmp_v3_report *)p->payload; ++ rep->igmp_v3_msgtype = IGMP_V3_MEMB_REPORT; ++ rep->igmp_v3_reserve1 = 0; ++ rep->igmp_v3_checksum = 0; ++ rep->igmp_v3_reserve2 = 0; ++ rep->igmp_v3_reccnt = PP_HTONS(1); ++ ++ rec = (struct igmp_v3_record *)(rep + 1); ++ if (group->v3_fmode == MCAST_EXCLUDE) { ++ rec->igmp_v3_rc_type = IGMP_V3_REC_TO_IN; ++ } else { ++ rec->igmp_v3_rc_type = IGMP_V3_REC_IS_IN; ++ } ++ rec->igmp_v3_rc_auxlen = 0; ++ rec->igmp_v3_rc_srccnt = 0; /* IS_IN (NULL) mean drop group */ ++ ip4_addr_set(&rec->igmp_v3_rc_group_address, &group->group_address); ++ rep->igmp_v3_checksum = inet_chksum(rep, IGMP_V3_REPORT_HLEN + IGMP_V3_RECORD_LEN(0)); ++ ++ } else { /* Report a group */ ++ ip4_addr_p_t src_array[LWIP_MCAST_SRC_TBL_SIZE]; ++ u16_t src_cnt; ++ u8_t fmode; ++ ++ src_cnt = mcast_ip4_filter_info(netif, &group->group_address, src_array, LWIP_MCAST_SRC_TBL_SIZE, &fmode); ++ LWIP_ASSERT("igmp_v3_send: multicast filter error!", !(!src_cnt && (fmode == MCAST_INCLUDE))); ++ ++ p = pbuf_alloc(PBUF_TRANSPORT, IGMP_V3_REPORT_HLEN + IGMP_V3_RECORD_LEN(src_cnt), PBUF_RAM); ++ if (p == NULL) { ++ LWIP_DEBUGF(IGMP_DEBUG, ("igmp_v3_send: not enough memory for igmp_v3_send\n")); ++ IGMP_STATS_INC(igmp.memerr); ++ return; ++ } ++ ++ rep = (struct igmp_v3_report *)p->payload; ++ rep->igmp_v3_msgtype = IGMP_V3_MEMB_REPORT; ++ rep->igmp_v3_reserve1 = 0; ++ rep->igmp_v3_checksum = 0; ++ rep->igmp_v3_reserve2 = 0; ++ rep->igmp_v3_reccnt = PP_HTONS(1); ++ ++ rec = (struct igmp_v3_record *)(rep + 1); ++ igmp_v3_build_record(rec, group, fmode, src_array, src_cnt); ++ rep->igmp_v3_checksum = inet_chksum(rep, IGMP_V3_REPORT_HLEN + IGMP_V3_RECORD_LEN(src_cnt)); ++ group->v3_last_reporter_flag = 1; /* Remember we were the last to report */ ++ } ++ ++ igmp_ip_output_if(p, &src, &v3_routers, netif); ++ pbuf_free(p); ++} ++ ++/** ++ * Send igmp v3 packet to report all groups. ++ */ ++static void ++igmp_v3_send_allgroups(struct netif *netif) ++{ ++ struct igmp_group *group; ++ struct igmp_v3_report *rep; ++ struct igmp_v3_record *rec; ++ struct pbuf *p, *p_rec; ++ ip4_addr_t src; ++ ip4_addr_p_t src_array[LWIP_MCAST_SRC_TBL_SIZE]; ++ u16_t src_cnt; ++ u16_t max_pkt_len = (u16_t)(netif->mtu ? netif->mtu : 0xffff); ++ u8_t fmode; ++ ++ ip4_addr_copy(src, *netif_ip4_addr(netif)); ++ ++ group = netif_igmp_data(netif); ++ if (group) { ++ group = group->next; /* do not report allsystem group */ ++ } ++ ++ if (!group) { ++ return; /* no group */ ++ } ++ ++ src_cnt = mcast_ip4_filter_info(netif, &group->group_address, src_array, LWIP_MCAST_SRC_TBL_SIZE, &fmode); ++ LWIP_ASSERT("igmp_v3_send: multicast filter error!", !(!src_cnt && (fmode == MCAST_INCLUDE))); ++ ++ while (group) { ++ p = pbuf_alloc(PBUF_TRANSPORT, IGMP_V3_REPORT_HLEN + IGMP_V3_RECORD_LEN(src_cnt), PBUF_RAM); ++ if (p == NULL) { ++ LWIP_DEBUGF(IGMP_DEBUG, ("igmp_v3_send_allgroups: not enough memory for igmp_v3_send_allgroups\n")); ++ IGMP_STATS_INC(igmp.memerr); ++ return; ++ } ++ ++ rep = (struct igmp_v3_report *)p->payload; ++ rep->igmp_v3_msgtype = IGMP_V3_MEMB_REPORT; ++ rep->igmp_v3_reserve1 = 0; ++ rep->igmp_v3_checksum = 0; ++ rep->igmp_v3_reserve2 = 0; ++ rep->igmp_v3_reccnt = PP_HTONS(1); ++ ++ rec = (struct igmp_v3_record *)(rep + 1); ++ igmp_v3_build_record(rec, group, fmode, src_array, src_cnt); ++ group->v3_last_reporter_flag = 1; /* Remember we were the last to report */ ++ ++cat_rec: ++ group = group->next; /* the next group */ ++ if (group) { ++ src_cnt = mcast_ip4_filter_info(netif, &group->group_address, src_array, LWIP_MCAST_SRC_TBL_SIZE, &fmode); ++ LWIP_ASSERT("igmp_v3_send: multicast filter error!", !(!src_cnt && (fmode == MCAST_INCLUDE))); ++ ++ if (p->tot_len + IGMP_V3_RECORD_LEN(src_cnt) < max_pkt_len) { /* can add a record? */ ++ p_rec = pbuf_alloc(PBUF_RAW, IGMP_V3_RECORD_LEN(src_cnt), PBUF_RAM); ++ if (p_rec) { ++ rep->igmp_v3_reccnt = PP_HTONS(PP_NTOHS(rep->igmp_v3_reccnt) + 1); /* add a record */ ++ ++ rec = (struct igmp_v3_record *)p_rec->payload; ++ igmp_v3_build_record(rec, group, fmode, src_array, src_cnt); ++ group->v3_last_reporter_flag = 1; /* Remember we were the last to report */ ++ pbuf_cat(p, p_rec); /* cat to tail */ ++ goto cat_rec; ++ ++ } else { ++ LWIP_DEBUGF(IGMP_DEBUG, ("igmp_v3_send_allgroups: not enough memory for igmp_v3_send_allgroups\n")); ++ IGMP_STATS_INC(igmp.memerr); ++ } ++ } ++ } ++ ++ rep->igmp_v3_checksum = inet_chksum_pbuf(p); ++ igmp_ip_output_if(p, &src, &v3_routers, netif); ++ pbuf_free(p); ++ } ++} ++ ++/** ++ * igmp v3 report trigger. ++ */ ++void ++igmp_v3_trigger(struct netif *netif, const ip4_addr_t *groupaddr) ++{ ++ struct igmp_group *group; ++ ++ /* find group */ ++ group = igmp_lookfor_group(netif, groupaddr); ++ if (group) { ++ igmp_v3_send(netif, group, IGMP_V3_MEMB_REPORT); ++ ++ igmp_v3_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR); ++ ++ /* Need to work out where this timer comes from */ ++ group->v3_group_state = IGMP_GROUP_DELAYING_MEMBER; ++ } ++} ++ ++#endif /* LWIP_IGMP_V3 */ + #endif /* LWIP_IPV4 && LWIP_IGMP */ +diff -Nur lwip-2.2.0init/src/core/mcast.c lwip-2.2.0/src/core/mcast.c +--- lwip-2.2.0init/src/core/mcast.c 1970-01-01 08:00:00.000000000 +0800 ++++ lwip-2.2.0/src/core/mcast.c 2024-04-02 19:15:03.867584000 +0800 +@@ -0,0 +1,605 @@ ++/** ++ * @file ++ * Multicast filter module\n ++ */ ++ ++/* ++ * Copyright (c) 2001-2004 Swedish Institute of Computer Science. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, ++ * are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote products ++ * derived from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT ++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT ++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY ++ * OF SUCH DAMAGE. ++ * ++ * This file is part of the lwIP TCP/IP stack. ++ * ++ * Author: Kylinos Technologies ++ * ++ */ ++ ++#include "lwip/opt.h" ++ ++#if LWIP_UDP || LWIP_RAW /* don't build if not configured for use in lwipopts.h */ ++ ++#include "lwip/err.h" ++#include "lwip/udp.h" ++#include "lwip/raw.h" ++#include "lwip/def.h" ++#include "lwip/mem.h" ++#include "lwip/netif.h" ++#include "lwip/errno.h" ++#include "lwip/ip_addr.h" ++#include "lwip/sockets.h" ++#include "lwip/mcast.h" ++ ++#include /* We need offsetof() */ ++ ++#if LWIP_IPV4 && LWIP_IGMP ++/** ++ * ipv4 multicast filter find ++ */ ++struct ip4_mc * ++mcast_ip4_mc_find(struct ip_mc *ipmc, struct netif *netif, const ip4_addr_t *multi_addr, struct ip4_mc **mc_prev) ++{ ++ struct ip4_mc *prev = NULL; ++ struct ip4_mc *mc; ++ ++ IP4_MC_FOREACH(ipmc, mc) { ++ if (ip4_addr_cmp(&mc->if_addr, netif_ip4_addr(netif)) && ++ ip4_addr_cmp(&mc->multi_addr, multi_addr)) { /* check interface and multicast address */ ++ if (mc_prev) { ++ *mc_prev = prev; ++ } ++ return mc; /* found! */ ++ } ++ prev = mc; ++ } ++ ++ return NULL; /* not found! */ ++} ++ ++/** ++ * ipv4 multicast filter find source ++ */ ++static struct igmp_src * ++mcast_ip4_mc_src_find(struct ip4_mc *mc, const ip4_addr_t *src_addr, struct igmp_src **src_prev) ++{ ++ struct igmp_src *prev = NULL; ++ struct igmp_src *src; ++ ++ IP4_MC_SRC_FOREACH(mc, src) { ++ if (ip4_addr_cmp(&src->src_addr, src_addr)) { /* check source address */ ++ if (src_prev) { ++ *src_prev = prev; ++ } ++ return src; /* found! */ ++ } ++ prev = src; ++ } ++ ++ return NULL; /* not found! */ ++} ++ ++/** ++ * ipv4 multicast filter remove all source ++ */ ++void ++mcast_ip4_mc_src_remove(struct igmp_src *src) ++{ ++ struct igmp_src *next; ++ ++ while (src) { ++ next = src->next; ++ mem_free(src); ++ src = next; ++ } ++} ++ ++#if LWIP_IGMP_V3 ++/** ++ * ipv4 multicast filter group source infomation (use ip4_addr_p_t for IGMPv3 speedup) ++ */ ++u16_t ++mcast_ip4_filter_info(struct netif *netif, const ip4_addr_t *multi_addr, ip4_addr_p_t addr_array[], u16_t arr_cnt, u8_t *fmode) ++{ ++ static ip4_addr_p_t in_tbl[LWIP_MCAST_SRC_TBL_SIZE]; ++ static ip4_addr_p_t ex_tbl[LWIP_MCAST_SRC_TBL_SIZE]; ++ ++ struct ip4_mc *mc; ++ struct igmp_src *src; ++ ip4_addr_t addr; /* for compare speed */ ++ u16_t i, j; ++ u16_t cnt, in_cnt = 0, ex_cnt = 0; ++ u16_t max_cnt = (u16_t)((arr_cnt > LWIP_MCAST_SRC_TBL_SIZE) ? LWIP_MCAST_SRC_TBL_SIZE : arr_cnt); ++ u8_t match = 0; ++ ++#define LWIP_IP4_MC_GET(pcb, pcbs, type, tbl, c) \ ++ for ((pcb) = (pcbs); (pcb) != NULL; (pcb) = (pcb)->next) { \ ++ mc = mcast_ip4_mc_find(&(pcb)->ipmc, netif, multi_addr, NULL); \ ++ if ((mc == NULL) || (mc->fmode != (type))) { \ ++ continue; \ ++ } \ ++ match = 1; /* group matched */ \ ++ IP4_MC_SRC_FOREACH(mc, src) { \ ++ if ((c) < max_cnt) { \ ++ ip4_addr_set(&(tbl)[(c)], &src->src_addr); /* save a source */ \ ++ (c)++; \ ++ } else { \ ++ *fmode = MCAST_EXCLUDE; /* table overflow, we need all this group packet */ \ ++ return (0); \ ++ } \ ++ } \ ++ } ++ ++#if LWIP_UDP ++ { ++ struct udp_pcb *pcb; ++ LWIP_IP4_MC_GET(pcb, udp_pcbs, MCAST_INCLUDE, in_tbl, in_cnt); /* copy all udp include source address to in_tbl[] */ ++ } ++#endif /* LWIP_UDP */ ++ ++#if LWIP_RAW ++ { ++ struct raw_pcb *pcb; ++ LWIP_IP4_MC_GET(pcb, raw_pcbs, MCAST_INCLUDE, in_tbl, in_cnt); /* copy all raw include source address to in_tbl[] */ ++ } ++#endif /* LWIP_UDP */ ++ ++#if LWIP_UDP ++ { ++ struct udp_pcb *pcb; ++ LWIP_IP4_MC_GET(pcb, udp_pcbs, MCAST_EXCLUDE, ex_tbl, ex_cnt); /* copy all udp exclude source address to ex_tbl[] */ ++ } ++#endif /* LWIP_UDP */ ++ ++#if LWIP_RAW ++ { ++ struct raw_pcb *pcb; ++ LWIP_IP4_MC_GET(pcb, raw_pcbs, MCAST_EXCLUDE, ex_tbl, ex_cnt); /* copy all raw exclude source address to ex_tbl[] */ ++ } ++#endif /* LWIP_UDP */ ++ ++ if (ex_cnt) { /* at least have one exclude source address */ ++ *fmode = MCAST_EXCLUDE; ++ for (i = 0; i < ex_cnt; i++) { ++ ip4_addr_set(&addr, &ex_tbl[i]); ++ for (j = 0; j < in_cnt; j++) { ++ if (ip4_addr_cmp(&addr, &in_tbl[j])) { /* check exclude conflict with include table */ ++ ip4_addr_set_any(&ex_tbl[i]); /* remove from exclude table */ ++ break; ++ } ++ } ++ } ++ ++ for (i = 0, cnt = 0; i < ex_cnt; i++) { ++ if (!ip4_addr_isany(&ex_tbl[i])) { ++ ip4_addr_set(&addr_array[cnt], &ex_tbl[i]); ++ cnt++; ++ } ++ } ++ ++ } else if (in_cnt) { /* at least have one include source address */ ++ *fmode = MCAST_INCLUDE; ++ for (i = 0; i < in_cnt; i++) { ++ ip4_addr_set(&addr_array[i], &in_tbl[i]); ++ } ++ cnt = i; ++ ++ } else { ++ if (match) { /* at least have one pcb matched */ ++ *fmode = MCAST_EXCLUDE; ++ } else { /* no match! */ ++ *fmode = MCAST_INCLUDE; ++ } ++ cnt = 0; ++ } ++ ++ return (cnt); ++} ++ ++/** ++ * ipv4 multicast filter source address interest (use ip4_addr_p_t for IGMPv3 speedup) ++ */ ++u8_t ++mcast_ip4_filter_interest(struct netif *netif, const ip4_addr_t *multi_addr, const ip4_addr_p_t src_addr[], u16_t arr_cnt) ++{ ++ static ip4_addr_p_t ip_tbl[LWIP_MCAST_SRC_TBL_SIZE]; ++ u16_t i, j, cnt; ++ u8_t fmode; ++ ++ cnt = mcast_ip4_filter_info(netif, multi_addr, ip_tbl, LWIP_MCAST_SRC_TBL_SIZE, &fmode); ++ if (fmode == MCAST_EXCLUDE) { ++ for (i = 0; i < cnt; i++) { ++ for (j = 0; j < arr_cnt; j++) { ++ if (ip4_addr_cmp(&src_addr[j], &ip_tbl[i])) { ++ return 0; ++ } ++ } ++ } ++ return 1; ++ ++ } else { ++ for (i = 0; i < cnt; i++) { ++ for (j = 0; j < arr_cnt; j++) { ++ if (ip4_addr_cmp(&src_addr[j], &ip_tbl[i])) { ++ return 1; ++ } ++ } ++ } ++ return 0; ++ } ++} ++#endif /* LWIP_IGMP_V3 */ ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++ ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++/** Join a multicast group (Can with a source specified) ++ * ++ * @param ipmc multicast filter control block ++ * @param netif the network interface which should join a new group. ++ * @param multi_addr the ipv6 address of the group to join ++ * @param src_addr multicast source address (can be NULL) ++ * @return lwIP error definitions ++ */ ++err_t ++mcast_join_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, const ip_addr_t *src_addr) ++{ ++#if LWIP_UDP ++ if (ipmc->proto == IPPROTO_UDP) { ++ err_t err; ++ struct udp_pcb *pcb; ++ /* prepare UDP pcb to udp_pcbs list */ ++ pcb = (struct udp_pcb *)((u8_t *)ipmc - offsetof(struct udp_pcb, ipmc)); ++ if (pcb->local_port == 0) { ++ err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); ++ if (err != ERR_OK) { ++ LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mcast_join_netif: forced port bind failed\n")); ++ return err; ++ } ++ } ++ } ++#endif /* LWIP_UDP */ ++ ++#if LWIP_IPV4 && LWIP_IGMP ++ if (IP_IS_V4(multi_addr)) { ++ struct ip4_mc *mc; ++ struct igmp_src *src; ++ ++ mc = mcast_ip4_mc_find(ipmc, netif, ip_2_ip4(multi_addr), NULL); ++ if (mc) { ++ if (src_addr) { ++ if ((mc->fmode == MCAST_EXCLUDE) && (mc->src)) { ++ return ERR_VAL; /* filter mode not include mode */ ++ } ++ src = mcast_ip4_mc_src_find(mc, ip_2_ip4(src_addr), NULL); ++ if (src) { ++ return ERR_ALREADY; /* already in source list */ ++ } ++ ++ src = (struct igmp_src *)mem_malloc(sizeof(struct igmp_src)); ++ if (src == NULL) { ++ return ERR_MEM; /* no memory */ ++ } ++ ip4_addr_set(&src->src_addr, ip_2_ip4(src_addr)); ++ src->next = mc->src; ++ mc->src = src; ++ mc->fmode = MCAST_INCLUDE; /* change to include mode */ ++ IP4_MC_TRIGGER_CALL(netif, ip_2_ip4(multi_addr)); /* trigger a report */ ++ } ++ return ERR_OK; ++ } ++ ++ mc = (struct ip4_mc *)mem_malloc(sizeof(struct ip4_mc)); /* Make a new mc */ ++ if (mc == NULL) { ++ igmp_leavegroup_netif(netif, ip_2_ip4(multi_addr)); ++ return ERR_MEM; /* no memory */ ++ } ++ ip4_addr_set(&mc->if_addr, netif_ip4_addr(netif)); ++ ip4_addr_set(&mc->multi_addr, ip_2_ip4(multi_addr)); ++ ++ if (src_addr) { /* have a source specified */ ++ mc->fmode = MCAST_INCLUDE; ++ src = (struct igmp_src *)mem_malloc(sizeof(struct igmp_src)); ++ if (src == NULL) { ++ mem_free(mc); ++ return ERR_MEM; /* no memory */ ++ } ++ ip4_addr_set(&src->src_addr, ip_2_ip4(src_addr)); ++ src->next = NULL; ++ mc->src = src; ++ ++ } else { ++ mc->fmode = MCAST_EXCLUDE; /* no source specified */ ++ mc->src = NULL; ++ } ++ ++ mc->next = ipmc->mc4; ++ ipmc->mc4 = mc; ++ igmp_joingroup_netif(netif, ip_2_ip4(multi_addr)); ++ } else {} ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++ return ERR_OK; ++} ++ ++/** Join a multicast group (Can with a source specified) ++ * ++ * @param ipmc multicast filter control block ++ * @param if_addr the network interface address. ++ * @param multi_addr the ipv6 address of the group to join ++ * @param src_addr multicast source address (can be NULL) ++ * @return lwIP error definitions ++ */ ++err_t ++mcast_join_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const ip_addr_t *multi_addr, const ip_addr_t *src_addr) ++{ ++ err_t err = ERR_VAL; /* no matching interface */ ++ ++#if LWIP_IPV4 && LWIP_IGMP ++ if (IP_IS_V4(multi_addr)) { ++ struct netif *netif; ++ ++ NETIF_FOREACH(netif) { ++ if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ip_2_ip4(if_addr)) || ip4_addr_cmp(netif_ip4_addr(netif), ip_2_ip4(if_addr))))) { ++ err = mcast_join_netif(ipmc, netif, multi_addr, src_addr); ++ if (err != ERR_OK) { ++ return (err); ++ } ++ } ++ } ++ } else {} ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++ return err; ++} ++ ++/** Leave or drop a source from group on a network interface. ++ * ++ * @param ipmc multicast filter control block ++ * @param netif the network interface which should leave group. ++ * @param multi_addr the address of the group to leave ++ * @param src_addr multicast source address ++ * @return lwIP error definitions ++ */ ++err_t ++mcast_leave_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, const ip_addr_t *src_addr) ++{ ++#if LWIP_IPV4 && LWIP_IGMP ++ if (IP_IS_V4(multi_addr)) { ++ struct ip4_mc *mc_prev; ++ struct ip4_mc *mc; ++ struct igmp_src *src_prev; ++ struct igmp_src *src; ++ ++ mc = mcast_ip4_mc_find(ipmc, netif, ip_2_ip4(multi_addr), &mc_prev); ++ if (mc == NULL) { ++ return ERR_VAL; ++ } ++ ++ if (src_addr) { ++ if ((mc->fmode == MCAST_EXCLUDE) && (mc->src)) { ++ return ERR_VAL; /* drop source membership must in include mode */ ++ } ++ ++ src = mcast_ip4_mc_src_find(mc, ip_2_ip4(src_addr), &src_prev); ++ if (src) { ++ if (src_prev) { ++ src_prev->next = src->next; ++ } else { ++ mc->src = src->next; ++ } ++ mem_free(src); ++ } else { ++ return ERR_VAL; ++ } ++ if (mc->src) { ++ IP4_MC_TRIGGER_CALL(netif, ip_2_ip4(multi_addr)); /* trigger a report */ ++ return ERR_OK; ++ } ++ } else { /* we want drop this group */ ++ mcast_ip4_mc_src_remove(mc->src); ++ } ++ ++ igmp_leavegroup_netif(netif, ip_2_ip4(multi_addr)); ++ if (mc_prev) { ++ mc_prev->next = mc->next; ++ } else { ++ ipmc->mc4 = mc->next; ++ } ++ mem_free(mc); ++ } else {} ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++ return ERR_OK; ++} ++ ++/** Leave or drop a source from group on a network interface. ++ * ++ * @param ipmc multicast filter control block ++ * @param if_addr the network interface address. ++ * @param multi_addr the address of the group to leave ++ * @param src_addr multicast source address ++ * @return lwIP error definitions ++ */ ++err_t ++mcast_leave_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const ip_addr_t *multi_addr, const ip_addr_t *src_addr) ++{ ++ err_t res, err = ERR_VAL; /* no matching interface */ ++ ++#if LWIP_IPV4 && LWIP_IGMP ++ if (IP_IS_V4(multi_addr)) { ++ struct netif *netif; ++ ++ NETIF_FOREACH(netif) { ++ if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ip_2_ip4(if_addr)) || ip4_addr_cmp(netif_ip4_addr(netif), ip_2_ip4(if_addr))))) { ++ res = mcast_leave_netif(ipmc, netif, multi_addr, src_addr); ++ if (err != ERR_OK) { ++ err = res; ++ } ++ } ++ } ++ } else {} ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++ return err; ++} ++ ++/** Add a block source address to a multicast group ++ * ++ * @param ipmc multicast filter control block ++ * @param netif the network interface which group we already join. ++ * @param multi_addr the address of the group to add source ++ * @param blk_addr block multicast source address ++ * @return lwIP error definitions ++ */ ++err_t ++mcast_block_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, const ip_addr_t *blk_addr) ++{ ++#if LWIP_IPV4 && LWIP_IGMP ++ if (IP_IS_V4(multi_addr)) { ++ struct ip4_mc *mc; ++ struct igmp_src *src; ++ ++ mc = mcast_ip4_mc_find(ipmc, netif, ip_2_ip4(multi_addr), NULL); ++ if (mc == NULL) { ++ return ERR_VAL; ++ } ++ if (mc->fmode != MCAST_EXCLUDE) { /* we must in exclude mode */ ++ return ERR_VAL; ++ } ++ ++ src = mcast_ip4_mc_src_find(mc, ip_2_ip4(blk_addr), NULL); ++ if (src == NULL) { ++ src = (struct igmp_src *)mem_malloc(sizeof(struct igmp_src)); ++ if (src == NULL) { ++ return ERR_MEM; ++ } ++ ip4_addr_set(&src->src_addr, ip_2_ip4(blk_addr)); ++ src->next = mc->src; ++ mc->src = src; ++ IP4_MC_TRIGGER_CALL(netif, ip_2_ip4(multi_addr)); /* trigger a report */ ++ return ERR_OK; ++ } ++ } else {} ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++ return EADDRINUSE; ++} ++ ++/** Add a block source address to a multicast group ++ * ++ * @param ipmc multicast filter control block ++ * @param if_addr the network interface address. ++ * @param multi_addr the address of the group to add source ++ * @param blk_addr block multicast source address ++ * @return lwIP error definitions ++ */ ++err_t ++mcast_block_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const ip_addr_t *multi_addr, const ip_addr_t *blk_addr) ++{ ++ err_t err = ERR_VAL; /* no matching interface */ ++ ++#if LWIP_IPV4 && LWIP_IGMP ++ if (IP_IS_V4(multi_addr)) { ++ struct netif *netif; ++ ++ NETIF_FOREACH(netif) { ++ if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ip_2_ip4(if_addr)) || ip4_addr_cmp(netif_ip4_addr(netif), ip_2_ip4(if_addr))))) { ++ err = mcast_block_netif(ipmc, netif, multi_addr, blk_addr); ++ if (err != ERR_OK) { ++ return (err); ++ } ++ } ++ } ++ } else {} ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++ return err; ++} ++ ++/** Remove a block source address from a multicast group ++ * ++ * @param ipmc multicast filter control block ++ * @param netif the network interface which group we already join. ++ * @param multi_addr the address of the group to add source ++ * @param unblk_addr unblock multicast source address ++ * @return lwIP error definitions ++ */ ++err_t ++mcast_unblock_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, const ip_addr_t *unblk_addr) ++{ ++#if LWIP_IPV4 && LWIP_IGMP ++ if (IP_IS_V4(multi_addr)) { ++ struct ip4_mc *mc; ++ struct igmp_src *src_prev; ++ struct igmp_src *src; ++ ++ mc = mcast_ip4_mc_find(ipmc, netif, ip_2_ip4(multi_addr), NULL); ++ if (mc == NULL) { ++ return ERR_VAL; ++ } ++ if (mc->fmode != MCAST_EXCLUDE) { /* we must in exclude mode */ ++ return ERR_VAL; ++ } ++ ++ src = mcast_ip4_mc_src_find(mc, ip_2_ip4(unblk_addr), &src_prev); ++ if (src == NULL) { ++ return ERR_VAL; ++ } ++ if (src_prev) { ++ src_prev->next = src->next; ++ } else { ++ mc->src = src->next; ++ } ++ mem_free(src); ++ IP4_MC_TRIGGER_CALL(netif, ip_2_ip4(multi_addr)); /* trigger a report */ ++ } else {} ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++ return ERR_OK; ++} ++ ++/** Remove a block source address from a multicast group ++ * ++ * @param ipmc multicast filter control block ++ * @param if_addr the network interface address. ++ * @param multi_addr the address of the group to add source ++ * @param unblk_addr unblock multicast source address ++ * @return lwIP error definitions ++ */ ++err_t ++mcast_unblock_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const ip_addr_t *multi_addr, const ip_addr_t *unblk_addr) ++{ ++ err_t res, err = ERR_VAL; /* no matching interface */ ++ ++#if LWIP_IPV4 && LWIP_IGMP ++ if (IP_IS_V4(multi_addr)) { ++ struct netif *netif; ++ ++ NETIF_FOREACH(netif) { ++ if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ip_2_ip4(if_addr)) || ip4_addr_cmp(netif_ip4_addr(netif), ip_2_ip4(if_addr))))) { ++ res = mcast_unblock_netif(ipmc, netif, multi_addr, unblk_addr); ++ if (err != ERR_OK) { ++ err = res; ++ } ++ } ++ } ++ } else {} ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++ return err; ++} ++ ++#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ ++ ++#endif /* LWIP_UDP || LWIP_RAW */ +diff -Nur lwip-2.2.0init/src/core/raw.c lwip-2.2.0/src/core/raw.c +--- lwip-2.2.0init/src/core/raw.c 2024-04-02 19:14:40.969584000 +0800 ++++ lwip-2.2.0/src/core/raw.c 2024-04-02 19:15:03.867584000 +0800 +@@ -63,10 +63,10 @@ + #include + + /** The list of RAW PCBs */ +-static struct raw_pcb *raw_pcbs; ++struct raw_pcb *raw_pcbs; + + static u8_t +-raw_input_local_match(struct raw_pcb *pcb, u8_t broadcast) ++raw_input_local_match(struct raw_pcb *pcb, u8_t broadcast, struct netif *inp) + { + LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */ + +@@ -88,6 +88,12 @@ + } + #endif /* LWIP_IPV4 && LWIP_IPV6 */ + ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++ if (ip_addr_ismulticast(ip_current_dest_addr())) { ++ return mcast_input_local_match(&pcb->ipmc, inp); ++ } ++#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ ++ + /* Only need to check PCB if incoming IP version matches PCB IP version */ + if (IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) { + #if LWIP_IPV4 +@@ -164,9 +170,20 @@ + /* loop through all raw pcbs until the packet is eaten by one */ + /* this allows multiple pcbs to match against the packet by design */ + while (pcb != NULL) { +- if ((pcb->protocol == proto) && raw_input_local_match(pcb, broadcast) && ++ if ((pcb->protocol == proto) && raw_input_local_match(pcb, broadcast, inp) && + (((pcb->flags & RAW_FLAGS_CONNECTED) == 0) || + ip_addr_eq(&pcb->remote_ip, ip_current_src_addr()))) { ++ if (pcb->min_ttl) { ++ if (ip_current_is_v6()) { ++ if (pcb->min_ttl > IP6H_HOPLIM(ip6_current_header())) { ++ continue; ++ } ++ } else { ++ if (pcb->min_ttl > IPH_TTL(ip4_current_header())) { ++ continue; ++ } ++ } ++ } + /* receive callback function available? */ + if (pcb->recv != NULL) { + u8_t eaten; +@@ -371,7 +388,26 @@ + /* For multicast-destined packets, use the user-provided interface index to + * determine the outgoing interface, if an interface index is set and a + * matching netif can be found. Otherwise, fall back to regular routing. */ +- netif = netif_get_by_index(pcb->mcast_ifindex); ++ if (pcb->mcast_ifindex != NETIF_NO_INDEX) { ++ netif = netif_get_by_index(pcb->mcast_ifindex); ++ } ++#if LWIP_IPV4 ++ else ++#if LWIP_IPV6 ++ if (IP_IS_V4(ipaddr)) ++#endif /* LWIP_IPV6 */ ++ { ++ /* IPv4 does not use source-based routing by default, so we use an ++ administratively selected interface for multicast by default. ++ However, this can be overridden by setting an interface address ++ in pcb->mcast_ip4 that is used for routing. If this routing lookup ++ fails, we try regular routing as though no override was set. */ ++ if (!ip4_addr_isany_val(pcb->mcast_ip4) && ++ !ip4_addr_cmp(&pcb->mcast_ip4, IP4_ADDR_BROADCAST)) { ++ netif = ip4_route_src(ip_2_ip4(&pcb->local_ip), &pcb->mcast_ip4); ++ } ++ } ++#endif /* LWIP_IPV4 */ + } + + if (netif == NULL) +@@ -450,6 +486,16 @@ + if (p->len < header_size) { + return ERR_VAL; + } ++#if CHECKSUM_GEN_IP ++ if (IP_IS_V4(dst_ip)) { ++ struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; ++ if (IPH_CHKSUM(iphdr) == 0) { ++ IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { ++ IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IPH_HL(iphdr) << 2)); ++ } ++ } ++ } ++#endif /* CHECKSUM_GEN_IP */ + /* @todo multicast loop support, if at all desired for this scenario.. */ + NETIF_SET_HINTS(netif, &pcb->netif_hints); + err = ip_output_if_hdrincl(p, src_ip, dst_ip, netif); +@@ -563,6 +609,11 @@ + { + struct raw_pcb *pcb2; + LWIP_ASSERT_CORE_LOCKED(); ++ ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++ mcast_pcb_remove(&pcb->ipmc); ++#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ ++ + /* pcb to be removed is first in list? */ + if (raw_pcbs == pcb) { + /* make list start at 2nd pcb */ +@@ -611,6 +662,9 @@ + raw_set_multicast_ttl(pcb, RAW_TTL); + #endif /* LWIP_MULTICAST_TX_OPTIONS */ + pcb_tci_init(pcb); ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++ pcb->ipmc.proto = IPPROTO_RAW; ++#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ + pcb->next = raw_pcbs; + raw_pcbs = pcb; + } +diff -Nur lwip-2.2.0init/src/core/udp.c lwip-2.2.0/src/core/udp.c +--- lwip-2.2.0init/src/core/udp.c 2024-04-02 19:14:40.969584000 +0800 ++++ lwip-2.2.0/src/core/udp.c 2024-04-02 19:15:03.868584000 +0800 +@@ -205,6 +205,12 @@ + return 1; + } + ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++ if (ip_addr_ismulticast(ip_current_dest_addr())) { ++ return mcast_input_local_match(&pcb->ipmc, inp); ++ } ++#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ ++ + /* Only need to check PCB if incoming IP version matches PCB IP version */ + if (IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) { + #if LWIP_IPV4 +@@ -347,6 +353,21 @@ + if ((pcb->remote_port == src) && + (ip_addr_isany_val(pcb->remote_ip) || + ip_addr_eq(&pcb->remote_ip, ip_current_src_addr()))) { ++ if (pcb->min_ttl) { ++ if (ip_current_is_v6()) { ++ if (pcb->min_ttl > IP6H_HOPLIM(ip6_current_header())) { ++ UDP_STATS_INC(udp.drop); ++ pbuf_free(p); ++ goto end; ++ } ++ } else { ++ if (pcb->min_ttl > IPH_TTL(ip4_current_header())) { ++ UDP_STATS_INC(udp.drop); ++ pbuf_free(p); ++ goto end; ++ } ++ } ++ } + /* the first fully matching PCB */ + if (prev != NULL) { + /* move the pcb to the front of udp_pcbs so that is +@@ -1321,6 +1342,10 @@ + + LWIP_ERROR("udp_remove: invalid pcb", pcb != NULL, return); + ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++ mcast_pcb_remove(&pcb->ipmc); ++#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ ++ + mib2_udp_unbind(pcb); + /* pcb to be removed is first in list? */ + if (udp_pcbs == pcb) { +@@ -1375,6 +1400,9 @@ + udp_set_multicast_ttl(pcb, UDP_TTL); + #endif /* LWIP_MULTICAST_TX_OPTIONS */ + pcb_tci_init(pcb); ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++ pcb->ipmc.proto = IPPROTO_UDP; ++#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ + } + return pcb; + } +diff -Nur lwip-2.2.0init/src/include/lwip/api.h lwip-2.2.0/src/include/lwip/api.h +--- lwip-2.2.0init/src/include/lwip/api.h 2024-04-02 19:14:40.965584000 +0800 ++++ lwip-2.2.0/src/include/lwip/api.h 2024-04-02 19:15:03.868584000 +0800 +@@ -89,6 +89,8 @@ + #if LWIP_NETBUF_RECVINFO + /** Received packet info will be recorded for this netconn */ + #define NETCONN_FLAG_PKTINFO 0x40 ++/** Received hoplim will be recorded for this netconn */ ++#define NETCONN_FLAG_HOPLIM 0x100 + #endif /* LWIP_NETBUF_RECVINFO */ + /** A FIN has been received but not passed to the application yet */ + #define NETCONN_FIN_RX_PENDING 0x80 +@@ -309,7 +311,7 @@ + s16_t linger; + #endif /* LWIP_SO_LINGER */ + /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */ +- u8_t flags; ++ u16_t flags; + #if LWIP_TCP + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores the message. +diff -Nur lwip-2.2.0init/src/include/lwip/igmp.h lwip-2.2.0/src/include/lwip/igmp.h +--- lwip-2.2.0init/src/include/lwip/igmp.h 2024-04-02 19:14:40.964584000 +0800 ++++ lwip-2.2.0/src/include/lwip/igmp.h 2024-04-02 19:15:03.868584000 +0800 +@@ -51,6 +51,13 @@ + extern "C" { + #endif + ++/* Multicast filter support */ ++struct igmp_src { ++ struct igmp_src *next; ++ /** the source address */ ++ ip4_addr_t src_addr; ++}; ++ + /* IGMP timer */ + #define IGMP_TMR_INTERVAL 100 /* Milliseconds */ + #define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL) +@@ -60,6 +67,10 @@ + #define IGMP_DEL_MAC_FILTER NETIF_DEL_MAC_FILTER + #define IGMP_ADD_MAC_FILTER NETIF_ADD_MAC_FILTER + ++#if LWIP_IGMP_V3 ++#define IGMP_FMODE_INIT 2 /* Not MCAST_INCLUDE or MCAST_EXCLUDE */ ++#endif /* LWIP_IGMP_V3 */ ++ + /** + * igmp group structure - there is + * a list of groups for each interface +@@ -84,6 +95,16 @@ + u16_t timer; + /** counter of simultaneous uses */ + u8_t use; ++#if LWIP_IGMP_V3 ++ /** Last report fmode */ ++ u8_t v3_fmode; ++ /** signifies we were the last person to report */ ++ u8_t v3_last_reporter_flag; ++ /** current state of the group */ ++ u8_t v3_group_state; ++ /** timer for reporting, negative is OFF */ ++ u16_t v3_timer; ++#endif /* LWIP_IGMP_V3 */ + }; + + /* Prototypes */ +@@ -106,6 +127,20 @@ + */ + #define netif_igmp_data(netif) ((struct igmp_group *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP)) + ++/** ++ * ipv4 multicast filter trigger function ++ */ ++#if LWIP_IGMP_V3 ++ void igmp_v3_trigger(struct netif *netif, const ip4_addr_t *groupaddr); ++ ++ /* IGMPv3 must install a trigger function to report multicast filter changes */ ++ ++#define IP4_MC_TRIGGER_CALL(netif, multi_addr) igmp_v3_trigger(netif, multi_addr) ++#else ++#define IP4_MC_TRIGGER_CALL(netif, multi_addr) ++#endif /* !LWIP_IGMP_V3 */ ++ ++ + #ifdef __cplusplus + } + #endif +diff -Nur lwip-2.2.0init/src/include/lwip/ip.h lwip-2.2.0/src/include/lwip/ip.h +--- lwip-2.2.0init/src/include/lwip/ip.h 2024-04-02 19:14:40.965584000 +0800 ++++ lwip-2.2.0/src/include/lwip/ip.h 2024-04-02 19:15:03.868584000 +0800 +@@ -85,7 +85,9 @@ + /* Type Of Service */ \ + u8_t tos; \ + /* Time To Live */ \ +- u8_t ttl \ ++ u8_t ttl; \ ++ /* min TTL */ \ ++ u8_t min_ttl \ + /* link layer address resolution hint */ \ + IP_PCB_NETIFHINT + +diff -Nur lwip-2.2.0init/src/include/lwip/mcast.h lwip-2.2.0/src/include/lwip/mcast.h +--- lwip-2.2.0init/src/include/lwip/mcast.h 1970-01-01 08:00:00.000000000 +0800 ++++ lwip-2.2.0/src/include/lwip/mcast.h 2024-04-02 19:15:03.868584000 +0800 +@@ -0,0 +1,117 @@ ++/** ++ * @file ++ * Multicast filter module\n ++ */ ++ ++/* ++ * Copyright (c) 2001-2004 Swedish Institute of Computer Science. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, ++ * are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote products ++ * derived from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT ++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT ++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY ++ * OF SUCH DAMAGE. ++ * ++ * This file is part of the lwIP TCP/IP stack. ++ * ++ * Author: Kylinos Technologies ++ * ++ */ ++#ifndef LWIP_HDR_MCAST_H ++#define LWIP_HDR_MCAST_H ++ ++#include "lwip/opt.h" ++ ++#if LWIP_UDP || LWIP_RAW /* don't build if not configured for use in lwipopts.h */ ++ ++#include "lwip/def.h" ++#include "lwip/ip.h" ++#include "lwip/ip_addr.h" ++#include "lwip/ip6_addr.h" ++#include "lwip/netif.h" ++#include "lwip/igmp.h" ++#include "lwip/mld6.h" ++#include "lwip/prot/ip4.h" ++#include "lwip/prot/ip6.h" ++ ++ ++#if LWIP_IPV4 && LWIP_IGMP ++/** the IPv4 multicast filter */ ++struct ip4_mc { ++ struct ip4_mc *next; ++ /** the interface address */ ++ ip4_addr_t if_addr; ++ /** the group address */ ++ ip4_addr_t multi_addr; ++ /** the source address list filter mode 0: EXCLUDE 1: INCLUDE */ ++ u8_t fmode; ++ /** the source address list */ ++ struct igmp_src *src; ++}; ++ ++/** The list of ip4_mc. */ ++#define IP4_MC_FOREACH(ipmc, mc) \ ++ for ((mc) = (ipmc)->mc4; (mc) != NULL; (mc) = (mc)->next) ++#define IP4_MC_SRC_FOREACH(mc, src) \ ++ for ((src) = (mc)->src; (src) != NULL; (src) = (src)->next) ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++ ++ ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++/* multicast filter control block */ ++struct ip_mc { ++#if !LWIP_SOCKET ++#define IPPROTO_UDP 17 ++#define IPPROTO_RAW 255 ++#endif /* !LWIP_SOCKET */ ++ u8_t proto; /* IPPROTO_UDP or IPPROTO_RAW */ ++#if LWIP_IPV4 && LWIP_IGMP ++ struct ip4_mc *mc4; ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++}; ++ ++#if LWIP_IPV4 && LWIP_IGMP && LWIP_IGMP_V3 ++/* IGMPv3 use the following function to get specified group of total multicast filter source address array */ ++u16_t mcast_ip4_filter_info(struct netif *netif, const ip4_addr_t *multi_addr, ip4_addr_p_t addr_array[], u16_t arr_cnt, u8_t *fmode); ++u8_t mcast_ip4_filter_interest(struct netif *netif, const ip4_addr_t *multi_addr, const ip4_addr_p_t src_addr[], u16_t arr_cnt); ++#endif /* LWIP_IPV4 && LWIP_IGMP && LWIP_IGMP_V3 */ ++ ++/* UDP or RAW use the following functions */ ++void mcast_pcb_remove(struct ip_mc *ipmc); ++u8_t mcast_input_local_match(struct ip_mc *ipmc, struct netif *inp); ++ ++/* The following functions is for Non-Socket API user */ ++err_t mcast_join_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, const ip_addr_t *src_addr); ++err_t mcast_join_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const ip_addr_t *multi_addr, const ip_addr_t *src_addr); ++err_t mcast_leave_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, const ip_addr_t *src_addr); ++err_t mcast_leave_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const ip_addr_t *multi_addr, const ip_addr_t *src_addr); ++err_t mcast_block_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, const ip_addr_t *blk_addr); ++err_t mcast_block_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const ip_addr_t *multi_addr, const ip_addr_t *blk_addr); ++err_t mcast_unblock_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, const ip_addr_t *unblk_addr); ++err_t mcast_unblock_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const ip_addr_t *multi_addr, const ip_addr_t *unblk_addr); ++ ++struct ip4_mc *mcast_ip4_mc_find(struct ip_mc *ipmc, struct netif *netif, const ip4_addr_t *multi_addr, struct ip4_mc **mc_prev); ++void mcast_ip4_mc_src_remove(struct igmp_src *src); ++ ++#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ ++ ++#endif /* LWIP_UDP || LWIP_RAW */ ++ ++#endif /* LWIP_HDR_MCAST_H */ +diff -Nur lwip-2.2.0init/src/include/lwip/netbuf.h lwip-2.2.0/src/include/lwip/netbuf.h +--- lwip-2.2.0init/src/include/lwip/netbuf.h 2024-04-02 19:14:40.964584000 +0800 ++++ lwip-2.2.0/src/include/lwip/netbuf.h 2024-04-02 19:15:03.868584000 +0800 +@@ -55,6 +55,8 @@ + #define NETBUF_FLAG_DESTADDR 0x01 + /** This netbuf includes a checksum */ + #define NETBUF_FLAG_CHKSUM 0x02 ++/** This netbuf has hoplim set */ ++#define NETBUF_FLAG_HOPLIM 0x80 + + /** "Network buffer" - contains data and addressing info */ + struct netbuf { +diff -Nur lwip-2.2.0init/src/include/lwip/opt.h lwip-2.2.0/src/include/lwip/opt.h +--- lwip-2.2.0init/src/include/lwip/opt.h 2024-04-02 19:14:40.965584000 +0800 ++++ lwip-2.2.0/src/include/lwip/opt.h 2024-04-02 19:15:03.868584000 +0800 +@@ -1126,9 +1126,12 @@ + #if !defined LWIP_IGMP || defined __DOXYGEN__ + #define LWIP_IGMP 1 + #endif ++ + #if !LWIP_IPV4 + #undef LWIP_IGMP + #define LWIP_IGMP 0 ++#undef LWIP_IGMP_V3 ++#define LWIP_IGMP_V3 0 + #endif + /** + * @} +diff -Nur lwip-2.2.0init/src/include/lwip/prot/igmp.h lwip-2.2.0/src/include/lwip/prot/igmp.h +--- lwip-2.2.0init/src/include/lwip/prot/igmp.h 2024-04-02 19:14:40.963584000 +0800 ++++ lwip-2.2.0/src/include/lwip/prot/igmp.h 2024-04-02 19:15:03.868584000 +0800 +@@ -49,6 +49,7 @@ + */ + #define IGMP_TTL 1 + #define IGMP_MINLEN 8 ++#define IGMP_V3_MINLEN 12 + #define ROUTER_ALERT 0x9404U + #define ROUTER_ALERTLEN 4 + +@@ -59,6 +60,7 @@ + #define IGMP_V1_MEMB_REPORT 0x12 /* Ver. 1 membership report */ + #define IGMP_V2_MEMB_REPORT 0x16 /* Ver. 2 membership report */ + #define IGMP_LEAVE_GROUP 0x17 /* Leave-group message */ ++#define IGMP_V3_MEMB_REPORT 0x22 /* Ver. 3 membership report */ + + /* Group membership states */ + #define IGMP_GROUP_NON_MEMBER 0 +@@ -83,6 +85,79 @@ + # include "arch/epstruct.h" + #endif + ++#if LWIP_IGMP_V3 /* RFC 3367 */ ++/** ++ * IGMPv3 query packet format. ++ */ ++#ifdef PACK_STRUCT_USE_INCLUDES ++# include "arch/bpstruct.h" ++#endif ++PACK_STRUCT_BEGIN ++struct igmp_v3_query { ++ PACK_STRUCT_FLD_8(u8_t igmp_v3_msgtype); ++ PACK_STRUCT_FLD_8(u8_t igmp_v3_maxresp); ++ PACK_STRUCT_FIELD(u16_t igmp_v3_checksum); ++ PACK_STRUCT_FLD_S(ip4_addr_p_t igmp_v3_group_address); ++ PACK_STRUCT_FLD_8(u8_t igmp_v3_sqrv); ++ PACK_STRUCT_FLD_8(u8_t igmp_v3_qqic); ++ PACK_STRUCT_FIELD(u16_t igmp_v3_srccnt); ++} PACK_STRUCT_STRUCT; ++PACK_STRUCT_END ++#ifdef PACK_STRUCT_USE_INCLUDES ++# include "arch/epstruct.h" ++#endif ++ ++#define IGMP_V3_QUERY_HLEN sizeof(struct igmp_v3_query) ++ ++/** ++ * IGMPv3 report packet header format. ++ */ ++#ifdef PACK_STRUCT_USE_INCLUDES ++# include "arch/bpstruct.h" ++#endif ++PACK_STRUCT_BEGIN ++struct igmp_v3_report { ++ PACK_STRUCT_FLD_8(u8_t igmp_v3_msgtype); ++ PACK_STRUCT_FLD_8(u8_t igmp_v3_reserve1); ++ PACK_STRUCT_FIELD(u16_t igmp_v3_checksum); ++ PACK_STRUCT_FIELD(u16_t igmp_v3_reserve2); ++ PACK_STRUCT_FIELD(u16_t igmp_v3_reccnt); ++} PACK_STRUCT_STRUCT; ++PACK_STRUCT_END ++#ifdef PACK_STRUCT_USE_INCLUDES ++# include "arch/epstruct.h" ++#endif ++ ++#define IGMP_V3_REPORT_HLEN sizeof(struct igmp_v3_report) ++ ++#define IGMP_V3_REC_IS_IN 0x01 /* Type MODE_IS_INCLUDE */ ++#define IGMP_V3_REC_IS_EX 0x02 /* Type MODE_IS_EXCLUDE */ ++#define IGMP_V3_REC_TO_IN 0x03 /* Type CHANGE_TO_INCLUDE_MODE */ ++#define IGMP_V3_REC_TO_EX 0x04 /* Type CHANGE_TO_EXCLUDE_MODE */ ++#define IGMP_V3_REC_ALLOW 0x05 /* Type ALLOW_NEW_SOURCES */ ++#define IGMP_V3_REC_BLOCK 0x06 /* Type BLOCK_OLD_SOURCES */ ++ ++/** ++ * IGMPv3 report packet group record format. ++ */ ++#ifdef PACK_STRUCT_USE_INCLUDES ++# include "arch/bpstruct.h" ++#endif ++PACK_STRUCT_BEGIN ++struct igmp_v3_record { ++ PACK_STRUCT_FLD_8(u8_t igmp_v3_rc_type); ++ PACK_STRUCT_FLD_8(u8_t igmp_v3_rc_auxlen); ++ PACK_STRUCT_FIELD(u16_t igmp_v3_rc_srccnt); ++ PACK_STRUCT_FLD_S(ip4_addr_p_t igmp_v3_rc_group_address); ++} PACK_STRUCT_STRUCT; ++PACK_STRUCT_END ++#ifdef PACK_STRUCT_USE_INCLUDES ++# include "arch/epstruct.h" ++#endif ++ ++#define IGMP_V3_RECORD_LEN(src_cnt) (sizeof(struct igmp_v3_record) + (src_cnt << 2)) ++#endif /* LWIP_IGMP_V3 */ ++ + #ifdef __cplusplus + } + #endif +diff -Nur lwip-2.2.0init/src/include/lwip/raw.h lwip-2.2.0/src/include/lwip/raw.h +--- lwip-2.2.0init/src/include/lwip/raw.h 2024-04-02 19:14:40.965584000 +0800 ++++ lwip-2.2.0/src/include/lwip/raw.h 2024-04-02 19:15:03.869584000 +0800 +@@ -47,6 +47,7 @@ + #include "lwip/ip.h" + #include "lwip/ip_addr.h" + #include "lwip/ip6_addr.h" ++#include "lwip/mcast.h" + + #ifdef __cplusplus + extern "C" { +@@ -82,12 +83,20 @@ + u8_t flags; + + #if LWIP_MULTICAST_TX_OPTIONS ++#if LWIP_IPV4 ++ /** outgoing network interface for multicast packets, by IPv4 address (if not 'any') */ ++ ip4_addr_t mcast_ip4; ++#endif /* LWIP_IPV4 */ + /** outgoing network interface for multicast packets, by interface index (if nonzero) */ + u8_t mcast_ifindex; + /** TTL for outgoing multicast packets */ + u8_t mcast_ttl; + #endif /* LWIP_MULTICAST_TX_OPTIONS */ + ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++ struct ip_mc ipmc; ++#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ ++ + /** receive callback function */ + raw_recv_fn recv; + /* user-supplied argument for the recv callback */ +@@ -98,6 +107,7 @@ + u8_t chksum_reqd; + #endif + }; ++extern struct raw_pcb *raw_pcbs; + + /* The following functions is the application layer interface to the + RAW code. */ +@@ -128,6 +138,10 @@ + #define raw_new_ip6(proto) raw_new_ip_type(IPADDR_TYPE_V6, proto) + + #if LWIP_MULTICAST_TX_OPTIONS ++#if LWIP_IPV4 ++#define raw_set_multicast_netif_addr(pcb, ip4addr) ip4_addr_copy((pcb)->mcast_ip4, *(ip4addr)) ++#define raw_get_multicast_netif_addr(pcb) (&(pcb)->mcast_ip4) ++#endif /* LWIP_IPV4 */ + #define raw_set_multicast_netif_index(pcb, idx) ((pcb)->mcast_ifindex = (idx)) + #define raw_get_multicast_netif_index(pcb) ((pcb)->mcast_ifindex) + #define raw_set_multicast_ttl(pcb, value) ((pcb)->mcast_ttl = (value)) +diff -Nur lwip-2.2.0init/src/include/lwip/sockets.h lwip-2.2.0/src/include/lwip/sockets.h +--- lwip-2.2.0init/src/include/lwip/sockets.h 2024-04-02 19:14:40.964584000 +0800 ++++ lwip-2.2.0/src/include/lwip/sockets.h 2024-04-02 19:15:03.869584000 +0800 +@@ -53,7 +53,7 @@ + #include "lwip/inet.h" + #include "lwip/errno.h" + #include "lwip/api.h" +- ++#include "lwip/mcast.h" + #include + + #ifdef __cplusplus +@@ -304,6 +304,10 @@ + #define IP_TOS 1 + #define IP_TTL 2 + #define IP_PKTINFO 8 ++#define IP_MINTTL 99 ++#define IP_HDRINCL 100 ++#define IP_OPTIONS 101 ++ + + #if LWIP_TCP + /* +@@ -357,24 +361,6 @@ + #endif /* GAZELLE_UDP_ENABLE */ + #endif /* LWIP_MULTICAST_TX_OPTIONS */ + +-#if LWIP_IGMP +-#if GAZELLE_UDP_ENABLE +-#define IP_ADD_MEMBERSHIP 35 +-#define IP_DROP_MEMBERSHIP 36 +-int lwip_socket_get_multi_memberships(int s, ip4_addr_t *if_addr, ip4_addr_t *multi_addr); +-#else +-/* +- * Options and types related to multicast membership +- */ +-#define IP_ADD_MEMBERSHIP 3 +-#define IP_DROP_MEMBERSHIP 4 +-#endif /* GAZELLE_UDP_ENABLE */ +- +-typedef struct ip_mreq { +- struct in_addr imr_multiaddr; /* IP multicast address of group */ +- struct in_addr imr_interface; /* local IP address of interface */ +-} ip_mreq; +-#endif /* LWIP_IGMP */ + + #if LWIP_IPV4 + struct in_pktinfo { +@@ -717,6 +703,112 @@ + int lwip_fcntl(int s, int cmd, int val); + #endif /* GAZELLE_ENABLE */ + ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++/* Protocol Independent Multicast API [RFC3678] */ ++#define MCAST_JOIN_GROUP 42 /* join an any-source group */ ++#define MCAST_BLOCK_SOURCE 43 /* block a source */ ++#define MCAST_UNBLOCK_SOURCE 44 /* unblock a source */ ++#define MCAST_LEAVE_GROUP 45 /* leave all sources for group */ ++#define MCAST_JOIN_SOURCE_GROUP 46 /* join a source-specific group */ ++#define MCAST_LEAVE_SOURCE_GROUP 47 /* leave a single source */ ++#define MCAST_MSFILTER 48 ++ ++#define LWIP_MCAST_SRC_TBL_SIZE 32 ++ ++ ++#if (LWIP_IPV4 && LWIP_IGMP) ++#if GAZELLE_UDP_ENABLE ++#define IP_ADD_MEMBERSHIP 35 ++#define IP_DROP_MEMBERSHIP 36 ++int lwip_socket_get_multi_memberships(int s, unsigned int if_idx, ip4_addr_t *multi_addr); ++#else ++/* ++ * Options and types related to multicast membership ++ */ ++#define IP_ADD_MEMBERSHIP 3 ++#define IP_DROP_MEMBERSHIP 4 ++#endif /* GAZELLE_UDP_ENABLE */ ++ ++typedef struct ip_mreq { ++ struct in_addr imr_multiaddr; /* IP multicast address of group */ ++ struct in_addr imr_interface; /* local IP address of interface */ ++} ip_mreq; ++ ++/* IPv4 Source Filter Multicast API [RFC3678] */ ++#define IP_UNBLOCK_SOURCE 37 /* unblock a source */ ++#define IP_BLOCK_SOURCE 38 /* block a source */ ++#define IP_ADD_SOURCE_MEMBERSHIP 39 /* join a source-specific group */ ++#define IP_DROP_SOURCE_MEMBERSHIP 40 /* drop a single source */ ++#define IP_MSFILTER 41 /* set/get msfilter */ ++/* ++ * Argument structure for IPv4 Multicast Source Filter APIs. [RFC3678] ++ */ ++struct ip_mreq_source { ++ struct in_addr imr_multiaddr; /* IP multicast address of group */ ++ struct in_addr imr_sourceaddr; /* IP address of source */ ++ struct in_addr imr_interface; /* local IP address of interface */ ++}; ++ ++#define IP_MSFILTER_SIZE(numsrc) \ ++ (sizeof(struct ip_msfilter) - sizeof(struct in_addr) \ ++ + (numsrc) * sizeof(struct in_addr)) ++ ++struct ip_msfilter { ++ struct in_addr imsf_multiaddr; ++ struct in_addr imsf_interface; ++ u32_t imsf_fmode; ++#define MCAST_EXCLUDE 0 ++#define MCAST_INCLUDE 1 ++ u32_t imsf_numsrc; ++ struct in_addr imsf_slist[1]; ++}; ++#endif /*(LWIP_IPV4 && LWIP_IGMP)*/ ++ ++/* +++ * Argument structures for Protocol-Independent Multicast Source +++ * Filter APIs. [RFC3678] +++ */ ++struct group_req { ++ u32_t gr_interface; /* interface index */ ++ struct sockaddr_storage gr_group; /* group address */ ++}; ++ ++struct group_source_req { ++ u32_t gsr_interface; /* interface index */ ++ struct sockaddr_storage gsr_group; /* group address */ ++ struct sockaddr_storage gsr_source; /* source address */ ++}; ++ ++#define GROUP_FILTER_SIZE(numsrc) \ ++ (sizeof(struct group_filter) - sizeof(struct sockaddr_storage) \ ++ + (numsrc) * sizeof(struct sockaddr_storage)) ++ ++struct group_filter { ++ u32_t gf_interface; /* interface index */ ++ struct sockaddr_storage gf_group; /* multicast address */ ++ u32_t gf_fmode; /* filter mode */ ++ u32_t gf_numsrc; /* number of sources */ ++ struct sockaddr_storage gf_slist[1]; /* interface index */ ++}; ++ ++err_t mcast_set_msfilter_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, const struct ip_msfilter *imsf); ++err_t mcast_set_groupfilter_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, const struct group_filter *gf); ++err_t mcast_get_msfilter_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, struct ip_msfilter *imsf, socklen_t *bufsz); ++err_t mcast_get_groupfilter_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, struct group_filter *gf, socklen_t *bufsz); ++ ++int mcast_sock_add_drop_membership(int s, struct ip_mc *ipmc, int optname, const struct ip_mreq *imr); ++int mcast_sock_add_drop_source_membership(int s, struct ip_mc *ipmc, int optname, const struct ip_mreq_source *imr); ++int mcast_sock_block_unblock_source(struct ip_mc *ipmc, int optname, const struct ip_mreq_source *imr); ++int mcast_sock_set_msfilter(struct ip_mc *ipmc, int optname, const struct ip_msfilter *imsf); ++int mcast_sock_get_msfilter(struct ip_mc *ipmc, int optname, struct ip_msfilter *imsf, socklen_t *size); ++int mcast_sock_join_leave_group(int s, struct ip_mc *ipmc, int optname, const struct group_req *gr); ++int mcast_sock_join_leave_source_group(int s, struct ip_mc *ipmc, int optname, const struct group_source_req *gsr); ++int mcast_sock_block_unblock_source_group(struct ip_mc *ipmc, int optname, const struct group_source_req *gsr); ++int mcast_sock_set_groupfilter(struct ip_mc *ipmc, int optname, const struct group_filter *gf); ++int mcast_sock_get_groupfilter(struct ip_mc *ipmc, int optname, struct group_filter *gf, socklen_t *size); ++ ++#endif /*(LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD)*/ ++ + const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size); + int lwip_inet_pton(int af, const char *src, void *dst); + +diff -Nur lwip-2.2.0init/src/include/lwip/udp.h lwip-2.2.0/src/include/lwip/udp.h +--- lwip-2.2.0init/src/include/lwip/udp.h 2024-04-02 19:14:40.964584000 +0800 ++++ lwip-2.2.0/src/include/lwip/udp.h 2024-04-02 19:15:03.869584000 +0800 +@@ -48,6 +48,7 @@ + #include "lwip/ip.h" + #include "lwip/ip6_addr.h" + #include "lwip/prot/udp.h" ++#include "lwip/mcast.h" + + #ifdef __cplusplus + extern "C" { +@@ -101,6 +102,10 @@ + u8_t mcast_ttl; + #endif /* LWIP_MULTICAST_TX_OPTIONS */ + ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++ struct ip_mc ipmc; ++#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ ++ + #if LWIP_UDPLITE + /** used for UDP_LITE only */ + u16_t chksum_len_rx, chksum_len_tx; +diff -Nur lwip-2.2.0init/src/include/lwipopts.h lwip-2.2.0/src/include/lwipopts.h +--- lwip-2.2.0init/src/include/lwipopts.h 2024-04-02 19:14:40.968584000 +0800 ++++ lwip-2.2.0/src/include/lwipopts.h 2024-04-02 19:16:42.759584000 +0800 +@@ -282,4 +282,14 @@ + #define LWIP_VLAN_PCP 1 + #define VLAN_LEN 4 + ++/* ++ ------------------------------------ ++ ---------- multicast options ---------- ++ ------------------------------------ ++*/ ++/** ++ * LWIP_IGMP_V3==1: Turn on IGMPv3 module. ++ */ ++#define LWIP_IGMP_V3 1 ++ + #endif /* __LWIPOPTS_H__ */ diff --git a/0120-enable-SO_REUSE_RXTOALL.patch b/0120-enable-SO_REUSE_RXTOALL.patch new file mode 100644 index 0000000..12fe332 --- /dev/null +++ b/0120-enable-SO_REUSE_RXTOALL.patch @@ -0,0 +1,25 @@ +From a90ad15caf8dacf54fa6433dfd748ff7248c8718 Mon Sep 17 00:00:00 2001 +From: liyunqing +Date: Fri, 22 Mar 2024 16:50:00 +0800 +Subject: [PATCH] enable SO_REUSE_RXTOALL + +--- + src/include/lwipopts.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index 3b8de83..1b4ec6d 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h +@@ -259,6 +259,8 @@ + + #define LWIP_SO_RCVTIMEO 1 + ++#define SO_REUSE_RXTOALL 1 ++ + /* + ------------------------------------ + --------- Debug log options -------- +-- +2.27.0 + diff --git a/0121-add-vlan-filter.patch b/0121-add-vlan-filter.patch new file mode 100644 index 0000000..1c37d76 --- /dev/null +++ b/0121-add-vlan-filter.patch @@ -0,0 +1,28 @@ +diff --git a/src/include/dpdk_version.h b/src/include/dpdk_version.h +index df3adb5..bf03d98 100644 +--- a/src/include/dpdk_version.h ++++ b/src/include/dpdk_version.h +@@ -56,6 +56,7 @@ + #define RTE_ETH_RX_OFFLOAD_UDP_CKSUM DEV_RX_OFFLOAD_UDP_CKSUM + #define RTE_ETH_RX_OFFLOAD_IPV4_CKSUM DEV_RX_OFFLOAD_IPV4_CKSUM + #define RTE_ETH_RX_OFFLOAD_VLAN_STRIP DEV_RX_OFFLOAD_VLAN_STRIP ++#define RTE_ETH_RX_OFFLOAD_VLAN_FILTER DEV_RX_OFFLOAD_VLAN_FILTER + + #define RTE_ETH_TX_OFFLOAD_IPV4_CKSUM DEV_TX_OFFLOAD_IPV4_CKSUM + #define RTE_ETH_TX_OFFLOAD_VLAN_INSERT DEV_TX_OFFLOAD_VLAN_INSERT +diff --git a/src/netif/ethernet.c b/src/netif/ethernet.c +index 0d8652b..d0d68b3 100644 +--- a/src/netif/ethernet.c ++++ b/src/netif/ethernet.c +@@ -122,6 +122,11 @@ ethernet_input(struct pbuf *p, struct netif *netif) + MIB2_STATS_NETIF_INC(netif, ifinerrors); + goto free_and_return; + } ++#if GAZELLE_ENABLE ++ if (netif->vlan_enable && !(netif->txol_flags & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) && VLAN_ID(vlan) != netif->vlan_tci) { ++ goto free_and_return; ++ } ++#endif + #if defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */ + #ifdef LWIP_HOOK_VLAN_CHECK + if (!LWIP_HOOK_VLAN_CHECK(netif, ethhdr, vlan)) { diff --git a/0122-support-mldv2.patch b/0122-support-mldv2.patch new file mode 100644 index 0000000..3a92755 --- /dev/null +++ b/0122-support-mldv2.patch @@ -0,0 +1,1867 @@ +From bd5283f4d24be4b982652b38a680264b4a3efdf4 Mon Sep 17 00:00:00 2001 +From: wanfeng +Date: Mon, 8 Apr 2024 10:31:20 +0800 +Subject: [PATCH] support mldv2 + +--- + src/api/api_msg.c | 60 +++-- + src/api/sockets.c | 262 +++++++++++++++++--- + src/core/ipv6/icmp6.c | 3 + + src/core/ipv6/mld6.c | 360 +++++++++++++++++++++++++++- + src/core/mcast.c | 438 +++++++++++++++++++++++++++++++++- + src/core/udp.c | 12 +- + src/include/lwip/api.h | 1 + + src/include/lwip/mcast.h | 35 +++ + src/include/lwip/mld6.h | 30 +++ + src/include/lwip/netbuf.h | 3 + + src/include/lwip/opt.h | 8 + + src/include/lwip/prot/icmp6.h | 2 + + src/include/lwip/prot/mld6.h | 79 ++++++ + src/include/lwip/sockets.h | 45 +++- + src/include/lwipopts.h | 5 + + 15 files changed, 1249 insertions(+), 94 deletions(-) + +diff --git a/src/api/api_msg.c b/src/api/api_msg.c +index 7cae567..f0a3e0b 100644 +--- a/src/api/api_msg.c ++++ b/src/api/api_msg.c +@@ -202,7 +202,23 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, + if (IP_IS_V4(addr)) { + struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; + ip_addr_copy_from_ip4(buf->toaddr, iphdr->dest); +- } else {} ++ } else ++#if LWIP_IPV6 ++ { ++ struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload; ++ ip_addr_copy_from_ip6_packed(buf->toaddr, ip6hdr->dest); ++ } ++#endif /* LWIP_IPV6 */ ++ } ++#if LWIP_IPV6 ++ if (conn->flags & NETCONN_FLAG_HOPLIM) { /* IPV6_HOPLIMIT */ ++ if (IP_IS_V6(addr)) { ++ struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload; ++ buf->flags |= NETBUF_FLAG_HOPLIM; /* IPV6_RECVHOPLIMIT (Hop limit) */ ++ buf->hoplim = IP6H_HOPLIM(ip6hdr); ++ } ++ } ++#endif /* LWIP_IPV6 */ + #endif /* LWIP_NETBUF_RECVINFO */ + + len = q->tot_len; +@@ -290,6 +306,15 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, + ip_addr_set(&buf->toaddr, ip_current_dest_addr()); + buf->toport_chksum = udphdr->dest; + } ++#if LWIP_IPV6 ++ if (conn->flags & NETCONN_FLAG_HOPLIM) { /* IPV6_HOPLIMIT */ ++ if (IP_IS_V6(addr)) { ++ struct ip6_hdr *ip6hdr = (struct ip6_hdr *)ip6_current_header(); ++ buf->flags |= NETBUF_FLAG_HOPLIM; /* IPV6_RECVHOPLIMIT (Hop limit) */ ++ buf->hoplim = IP6H_HOPLIM(ip6hdr); ++ } ++ } ++#endif /* LWIP_IPV6 */ + #endif /* LWIP_NETBUF_RECVINFO */ + } + +@@ -2084,25 +2109,11 @@ lwip_netconn_do_join_leave_group(void *m) + #if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { + #if LWIP_UDP +-#if LWIP_IPV6 && LWIP_IPV6_MLD +- if (NETCONNTYPE_ISIPV6(msg->conn->type)) { +- if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { +- msg->err = mld6_joingroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), +- ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); +- } else { +- msg->err = mld6_leavegroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), +- ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); +- } +- } else { +-#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ +-#if LWIP_IGMP + if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { + msg->err = mcast_join_group(&msg->conn->pcb.udp->ipmc, API_EXPR_REF(msg->msg.jl.netif_addr), API_EXPR_REF(msg->msg.jl.multiaddr), NULL); + } else { + msg->err = mcast_leave_group(&msg->conn->pcb.udp->ipmc, API_EXPR_REF(msg->msg.jl.netif_addr), API_EXPR_REF(msg->msg.jl.multiaddr), NULL); + } +-#endif /*LWIP_IGMP*/ +- } + #else + msg->err = ERR_VAL; + #endif /* LWIP_UDP */ +@@ -2146,30 +2157,15 @@ lwip_netconn_do_join_leave_group_netif(void *m) + #if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { + #if LWIP_UDP +-#if LWIP_IPV6 && LWIP_IPV6_MLD +- if (NETCONNTYPE_ISIPV6(msg->conn->type)) { +- if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { +- msg->err = mld6_joingroup_netif(netif, +- ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); +- } else { +- msg->err = mld6_leavegroup_netif(netif, +- ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); +- } +- } else +-#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ +- { +-#if LWIP_IGMP +- if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { ++ if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { + msg->err = mcast_join_netif(&msg->conn->pcb.udp->ipmc, netif, API_EXPR_REF(msg->msg.jl.multiaddr), NULL); + } else { + msg->err = mcast_leave_netif(&msg->conn->pcb.udp->ipmc, netif, API_EXPR_REF(msg->msg.jl.multiaddr), NULL); + } +-#endif /*LWIP_IGMP*/ + #else + msg->err = ERR_VAL; + #endif /* LWIP_UDP */ +- } +- } else if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_RAW) { ++ } else if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_RAW) { + #if LWIP_RAW + if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { + msg->err = mcast_join_netif(&msg->conn->pcb.raw->ipmc, netif, API_EXPR_REF(msg->msg.jl.multiaddr), NULL); +diff --git a/src/api/sockets.c b/src/api/sockets.c +index 0caebdd..6b2f5ee 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -3936,34 +3936,43 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ + #if LWIP_IPV6_MLD + case IPV6_JOIN_GROUP: + case IPV6_LEAVE_GROUP: { +- /* If this is a TCP or a RAW socket, ignore these options. */ +- err_t mld6_err; +- struct netif *netif; +- ip6_addr_t multi_addr; +- const struct ipv6_mreq *imr = (const struct ipv6_mreq *)optval; +- LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ipv6_mreq, NETCONN_UDP); +- inet6_addr_to_ip6addr(&multi_addr, &imr->ipv6mr_multiaddr); +- LWIP_ASSERT("Invalid netif index", imr->ipv6mr_interface <= 0xFFu); +- netif = netif_get_by_index((u8_t)imr->ipv6mr_interface); +- if (netif == NULL) { +- err = EADDRNOTAVAIL; +- break; ++ LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, struct ipv6_mreq); ++#if LWIP_UDP ++ if (NETCONNTYPE_GROUPV6(netconn_type(sock->conn)) == NETCONN_UDP_IPV6) { ++ err = mcast_sock_ipv6_add_drop_membership(s, &sock->conn->pcb.udp->ipmc, optname, (const struct ipv6_mreq *)optval); ++ } else ++#endif /* LWIP_UDP */ ++#if LWIP_RAW ++ if (NETCONNTYPE_GROUPV6(netconn_type(sock->conn)) == NETCONN_RAW_IPV6) { ++ err = mcast_sock_ipv6_add_drop_membership(s, &sock->conn->pcb.raw->ipmc, optname, (const struct ipv6_mreq *)optval); ++ } else ++#endif /* LWIP_RAW */ ++ { ++ done_socket(sock); ++ return ENOPROTOOPT; + } +- +- if (optname == IPV6_JOIN_GROUP) { +- if (!lwip_socket_register_mld6_membership(s, imr->ipv6mr_interface, &multi_addr)) { +- /* cannot track membership (out of memory) */ +- err = ENOMEM; +- mld6_err = ERR_OK; +- } else { +- mld6_err = mld6_joingroup_netif(netif, &multi_addr); +- } +- } else { +- mld6_err = mld6_leavegroup_netif(netif, &multi_addr); +- lwip_socket_unregister_mld6_membership(s, imr->ipv6mr_interface, &multi_addr); ++ } ++ break; ++ case MCAST_JOIN_GROUP: ++ case MCAST_LEAVE_GROUP: { ++ LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, struct group_req); ++ if (((const struct group_req *)optval)->gr_group.ss_family != AF_INET6) { ++ done_socket(sock); ++ return EINVAL; + } +- if (mld6_err != ERR_OK) { +- err = EADDRNOTAVAIL; ++#if LWIP_UDP ++ if (NETCONNTYPE_GROUPV6(netconn_type(sock->conn)) == NETCONN_UDP_IPV6) { ++ err = mcast_sock_join_leave_group(s, &sock->conn->pcb.udp->ipmc, optname, (const struct group_req *)optval); ++ } else ++#endif /* LWIP_UDP */ ++#if LWIP_RAW ++ if (NETCONNTYPE_GROUPV6(netconn_type(sock->conn)) == NETCONN_RAW_IPV6) { ++ err = mcast_sock_join_leave_group(s, &sock->conn->pcb.raw->ipmc, optname, (const struct group_req *)optval); ++ } else ++#endif /* LWIP_RAW */ ++ { ++ done_socket(sock); ++ return ENOPROTOOPT; + } + } + break; +@@ -4486,17 +4495,13 @@ lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_ + if (!sock) { + return 0; + } +- + SYS_ARCH_DECL_PROTECT(lev); + SYS_ARCH_PROTECT(lev); ++#if GAZELLE_ENABLE ++ i = s; ++#else + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { +- if ((socket_ipv6_multicast_memberships[i].sock == sock) && +- (socket_ipv6_multicast_memberships[i].if_idx == if_idx) && +- ip6_addr_cmp(&socket_ipv6_multicast_memberships[i].multi_addr, multi_addr)) { +- done_socket(sock); +- return 1; +- } +- ++#endif + if (socket_ipv6_multicast_memberships[i].sock == NULL) { + socket_ipv6_multicast_memberships[i].sock = sock; + socket_ipv6_multicast_memberships[i].if_idx = (u8_t)if_idx; +@@ -4504,7 +4509,9 @@ lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_ + done_socket(sock); + return 1; + } ++#if !GAZELLE_ENABLE + } ++#endif + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + return 0; +@@ -4524,19 +4531,26 @@ lwip_socket_unregister_mld6_membership(int s, unsigned int if_idx, const ip6_add + if (!sock) { + return; + } +- + SYS_ARCH_DECL_PROTECT(lev); + SYS_ARCH_PROTECT(lev); ++#if GAZELLE_ENABLE ++ i = s; ++#else + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { ++#endif + if ((socket_ipv6_multicast_memberships[i].sock == sock) && + (socket_ipv6_multicast_memberships[i].if_idx == if_idx) && +- ip6_addr_cmp(&socket_ipv6_multicast_memberships[i].multi_addr, multi_addr)) { ++ ip6_addr_cmp(&socket_ipv6_multicast_memberships[i].multi_addr, multi_addr)) { + socket_ipv6_multicast_memberships[i].sock = NULL; + socket_ipv6_multicast_memberships[i].if_idx = NETIF_NO_INDEX; + ip6_addr_set_zero(&socket_ipv6_multicast_memberships[i].multi_addr); ++#if !GAZELLE_ENABLE + break; ++#endif + } ++#if !GAZELLE_ENABLE + } ++#endif + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + } +@@ -4556,7 +4570,11 @@ lwip_socket_drop_registered_mld6_memberships(int s) + } + SYS_ARCH_DECL_PROTECT(lev); + SYS_ARCH_PROTECT(lev); ++#if GAZELLE_ENABLE ++ i = s; ++#else + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { ++#endif + if (socket_ipv6_multicast_memberships[i].sock == sock) { + ip_addr_t multi_addr; + u8_t if_idx; +@@ -4570,7 +4588,9 @@ lwip_socket_drop_registered_mld6_memberships(int s) + + netconn_join_leave_group_netif(sock->conn, &multi_addr, if_idx, NETCONN_LEAVE); + } ++#if !GAZELLE_ENABLE + } ++#endif + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + } +@@ -4597,6 +4617,25 @@ mcast_pcb_remove(struct ip_mc *ipmc) + } + } + #endif /* LWIP_IPV4 && LWIP_IGMP */ ++ ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ { ++ struct ip6_mc *mc, *next; ++ struct netif *netif; ++ ++ mc = ipmc->mc6; ++ while (mc) { ++ next = mc->next; ++ mcast_ip6_mc_src_remove(mc->src); ++ netif = netif_get_by_index(mc->if_idx); ++ if (netif) { ++ mld6_leavegroup_netif(netif, &mc->multi_addr); ++ } ++ mem_free(mc); ++ mc = next; ++ } ++ } ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ + } + + /** Common code to see if the current input multicast packet matches the pcb +@@ -4637,8 +4676,38 @@ mcast_input_local_match(struct ip_mc *ipmc, struct netif *inp) + } + } + } +- } else {} ++ } else + #endif /* LWIP_IPV4 && LWIP_IGMP */ ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ struct mld6_src *src; ++ struct ip6_mc *mc; ++ ip6_addr_t *multi_addr = ip6_current_dest_addr(); ++ ip6_addr_t *src_addr = ip6_current_src_addr(); ++ ++ IP6_MC_FOREACH(ipmc, mc) { ++ if (((mc->if_idx == NETIF_NO_INDEX) || (mc->if_idx == netif_get_index(inp))) && ++ ip6_addr_cmp_zoneless(&mc->multi_addr, multi_addr)) { ++ if (mc->fmode == MCAST_EXCLUDE) { ++ IP6_MC_SRC_FOREACH(mc, src) { ++ if (ip6_addr_cmp_zoneless(&src->src_addr, src_addr)) { ++ return 0; ++ } ++ } ++ return 1; /* MCAST_EXCLUDE src_addr must not in src list */ ++ ++ } else { /* MCAST_INCLUDE */ ++ IP6_MC_SRC_FOREACH(mc, src) { ++ if (ip6_addr_cmp_zoneless(&src->src_addr, src_addr)) { ++ return 1; ++ } ++ } ++ return 0; /* MCAST_INCLUDE src_addr must in src list */ ++ } ++ } ++ } ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ ++ } + return 0; + } + +@@ -4722,6 +4791,125 @@ mcast_sock_add_drop_membership(int s, struct ip_mc *ipmc, int optname, const str + out: + return (u8_t)err_to_errno(err); + } ++ ++/** ++ * setsockopt() MCAST_JOIN_GROUP / MCAST_LEAVE_GROUP command ++ */ ++int ++mcast_sock_join_leave_group(int s, struct ip_mc *ipmc, int optname, const struct group_req *gr) ++{ ++ struct netif *netif; ++ ip_addr_t multi_addr; ++ err_t err; ++ u8_t if_idx; ++ ++ if (gr->gr_group.ss_family == AF_INET) { ++ inet_addr_to_ip4addr(ip_2_ip4(&multi_addr), &(((struct sockaddr_in *)&(gr->gr_group))->sin_addr)); ++ IP_SET_TYPE_VAL(multi_addr, IPADDR_TYPE_V4); ++ if (!ip4_addr_ismulticast(ip_2_ip4(&multi_addr))) { ++ return EADDRNOTAVAIL; ++ } ++ ++ } else if (gr->gr_group.ss_family == AF_INET6) { ++ inet6_addr_to_ip6addr(ip_2_ip6(&multi_addr), &(((struct sockaddr_in6 *)&(gr->gr_group))->sin6_addr)); ++ IP_SET_TYPE_VAL(multi_addr, IPADDR_TYPE_V6); ++ if (!ip6_addr_ismulticast(ip_2_ip6(&multi_addr))) { ++ return EADDRNOTAVAIL; ++ } ++ ++ } else { ++ return EADDRNOTAVAIL; ++ } ++ ++ if (gr->gr_interface) { ++ netif = netif_get_by_index((u8_t)gr->gr_interface); ++ } else { ++ netif = netif_default; /* To default network interface */ ++ } ++ if (netif == NULL) { ++ return ENXIO; ++ } ++ ++ if_idx = netif_get_index(netif); ++ if (optname == MCAST_JOIN_GROUP) { ++#if LWIP_IPV4 && LWIP_IGMP ++ if (IP_IS_V4(&multi_addr)) { ++ if (!lwip_socket_register_membership(s, if_idx, ip_2_ip4(&multi_addr))) { ++ /* cannot track membership (out of memory) */ ++ err = ENOMEM; ++ goto out; ++ } ++ } else ++#endif ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ if (!lwip_socket_register_mld6_membership(s, if_idx, ip_2_ip6(&multi_addr))) { ++ /* cannot track membership (out of memory) */ ++ err = ENOMEM; ++ goto out; ++ } ++#endif ++ } ++ ++ err = mcast_join_netif(ipmc, netif, &multi_addr, NULL); ++ } else { ++ err = mcast_leave_netif(ipmc, netif, &multi_addr, NULL); ++#if LWIP_IPV4 && LWIP_IGMP ++ if (IP_IS_V4(&multi_addr)) { ++ lwip_socket_unregister_membership(s, if_idx, ip_2_ip4(&multi_addr)); ++ } else ++#endif ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ lwip_socket_unregister_mld6_membership(s, if_idx, ip_2_ip6(&multi_addr)); ++#endif ++ } ++ } ++out: ++ return err_to_errno(err); ++} ++ ++/** ++ * setsockopt() IPV6_JOIN_GROUP / IPV6_LEAVE_GROUP command ++ */ ++int ++mcast_sock_ipv6_add_drop_membership(int s, struct ip_mc *ipmc, int optname, const struct ipv6_mreq *imr) ++{ ++ struct netif *netif; ++ ip_addr_t multi_addr; ++ err_t err; ++ ++ inet6_addr_to_ip6addr(ip_2_ip6(&multi_addr), &imr->ipv6mr_multiaddr); ++ IP_SET_TYPE_VAL(multi_addr, IPADDR_TYPE_V6); ++ ++ if (!ip6_addr_ismulticast(ip_2_ip6(&multi_addr))) { ++ return EADDRNOTAVAIL; ++ } ++ ++ if (imr->ipv6mr_interface) { ++ netif = netif_get_by_index((u8_t)imr->ipv6mr_interface); ++ } else { ++ netif = netif_default; /* To default network interface */ ++ } ++ if (netif == NULL) { ++ return ENXIO; ++ } ++ ++ u8_t if_idx = netif_get_index(netif); ++ if (optname == IPV6_JOIN_GROUP) { ++ if (!lwip_socket_register_mld6_membership(s, if_idx, ip_2_ip6(&multi_addr))) { ++ /* cannot track membership (out of memory) */ ++ err = ENOMEM; ++ goto out; ++ } ++ err = mcast_join_netif(ipmc, netif, &multi_addr, NULL); ++ } else { ++ err = mcast_leave_netif(ipmc, netif, &multi_addr, NULL); ++ lwip_socket_unregister_mld6_membership(s, if_idx, ip_2_ip6(&multi_addr)); ++ } ++out: ++ return err_to_errno(err); ++} + #endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD)*/ + + #if GAZELLE_ENABLE +diff --git a/src/core/ipv6/icmp6.c b/src/core/ipv6/icmp6.c +index ed0bd7b..143cb20 100644 +--- a/src/core/ipv6/icmp6.c ++++ b/src/core/ipv6/icmp6.c +@@ -129,6 +129,9 @@ icmp6_input(struct pbuf *p, struct netif *inp) + case ICMP6_TYPE_MLQ: + case ICMP6_TYPE_MLR: + case ICMP6_TYPE_MLD: ++#if LWIP_IPV6_MLD_V2 ++ case ICMP6_TYPE_MLR2: ++#endif + mld6_input(p, inp); + return; + #endif +diff --git a/src/core/ipv6/mld6.c b/src/core/ipv6/mld6.c +index ac4fb01..29c45bc 100644 +--- a/src/core/ipv6/mld6.c ++++ b/src/core/ipv6/mld6.c +@@ -66,6 +66,7 @@ + #include "lwip/netif.h" + #include "lwip/memp.h" + #include "lwip/stats.h" ++#include "lwip/sockets.h" + + #include + +@@ -80,12 +81,22 @@ + #define MLD6_GROUP_DELAYING_MEMBER 1 + #define MLD6_GROUP_IDLE_MEMBER 2 + ++#define MLD6_MINLEN 12 ++#define MLD6_V2_MINLEN 16 ++ + /* Forward declarations. */ + static struct mld_group *mld6_new_group(struct netif *ifp, const ip6_addr_t *addr); + static err_t mld6_remove_group(struct netif *netif, struct mld_group *group); + static void mld6_delayed_report(struct mld_group *group, u16_t maxresp); + static void mld6_send(struct netif *netif, struct mld_group *group, u8_t type); ++static void mld6_timeout(struct netif *netif, struct mld_group *group); ++ + ++#if LWIP_IPV6_MLD_V2 ++static void mld6_v2_timeout(struct netif *netif, struct mld_group *group); ++static void mld6_v2_delayed_report(struct mld_group *group, u16_t maxresp_in); ++static void mld6_v2_send(struct netif *netif, struct mld_group *group, u8_t type); ++#endif + + /** + * Stop MLD processing on interface +@@ -128,6 +139,9 @@ mld6_report_groups(struct netif *netif) + + while (group != NULL) { + mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); ++#if LWIP_IPV6_MLD_V2 ++ mld6_v2_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); ++#endif + group = group->next; + } + } +@@ -177,6 +191,12 @@ mld6_new_group(struct netif *ifp, const ip6_addr_t *addr) + group->last_reporter_flag = 0; + group->use = 0; + group->next = netif_mld6_data(ifp); ++#if LWIP_IPV6_MLD_V2 ++ group->v2_fmode = MLD6_FMODE_INIT; ++ group->v2_last_reporter_flag = 0; ++ group->v2_group_state = MLD6_GROUP_IDLE_MEMBER; ++ group->v2_timer = 0; ++#endif + + netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, group); + } +@@ -244,6 +264,58 @@ mld6_input(struct pbuf *p, struct netif *inp) + + switch (mld_hdr->type) { + case ICMP6_TYPE_MLQ: /* Multicast listener query. */ ++#if LWIP_IPV6_MLD_V2 ++ if (p->len >= MLD6_V2_MINLEN) { ++ struct mld_v2_query *mld_v2_hdr = (struct mld_v2_query *)p->payload; ++ ++ /* Is it a general query? */ ++ if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) && ++ ip6_addr_isany(&(mld_v2_hdr->multicast_address))) { ++ MLD6_STATS_INC(mld6.rx_general); ++ /* Report all groups, except all nodes group, and if-local groups. */ ++ group = netif_mld6_data(inp); ++ while (group != NULL) { ++ if ((!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) && ++ (!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) { ++ mld6_v2_delayed_report(group, lwip_ntohs(mld_hdr->max_resp_delay)); ++ } ++ group = group->next; ++ } ++ } else { /* query to a specific group ? */ ++ if (!ip6_addr_isany(&(mld_v2_hdr->multicast_address))) { ++ u16_t src_num = PP_NTOHS(mld_v2_hdr->src_num); ++ ip6_addr_p_t *src_buf; ++ u16_t src_buf_size = src_num << 4; ++ ip6_addr_t group_addr; ++ ++ MLD6_STATS_INC(mld6.rx_group); ++ ip6_addr_copy(group_addr, mld_v2_hdr->multicast_address); ++ group = mld6_lookfor_group(inp, &group_addr); ++ ++ if (0 == src_num) { ++ if (group != NULL) { ++ /* Schedule a report. */ ++ mld6_v2_delayed_report(group, lwip_ntohs(mld_v2_hdr->max_resp_delay)); ++ } ++ } else { ++ src_buf = (ip6_addr_p_t *)mem_malloc(src_buf_size); ++ if (src_buf == NULL) { ++ pbuf_free(p); ++ MLD6_STATS_INC(mld6.memerr); ++ LWIP_DEBUGF(MLD6_DEBUG, ("mld6_input: not enough memory for mld6_input\n")); ++ return; ++ } ++ pbuf_copy_partial(p, src_buf, src_buf_size, MLD_V2_QUERY_HLEN); ++ if (mcast_ip6_filter_interest(inp, (const ip6_addr_t *)&group_addr, src_buf, src_num)) { ++ /* We interest! */ ++ mld6_v2_delayed_report(group, lwip_ntohs(mld_v2_hdr->max_resp_delay)); ++ } ++ } ++ } ++ } ++ ++ } ++#endif + /* Is it a general query? */ + if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) && + ip6_addr_isany(&(mld_hdr->multicast_address))) { +@@ -381,6 +453,10 @@ mld6_joingroup_netif(struct netif *netif, const ip6_addr_t *groupaddr) + MLD6_STATS_INC(mld6.tx_report); + mld6_send(netif, group, ICMP6_TYPE_MLR); + mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); ++#if LWIP_IPV6_MLD_V2 ++ mld6_v2_send(netif, group, ICMP6_TYPE_MLR2); ++ mld6_v2_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); ++#endif + } + + /* Increment group use */ +@@ -464,6 +540,13 @@ mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr) + MLD6_STATS_INC(mld6.tx_leave); + mld6_send(netif, group, ICMP6_TYPE_MLD); + } ++#if LWIP_IPV6_MLD_V2 ++ /* If we are the last reporter for this group */ ++ if (group->v2_last_reporter_flag) { ++ MLD6_STATS_INC(mld6.tx_leave); ++ mld6_v2_send(netif, group, ICMP6_TYPE_MLD); ++ } ++#endif + + /* Disable the group at the MAC level */ + if (netif->mld_mac_filter != NULL) { +@@ -485,6 +568,51 @@ mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr) + return ERR_VAL; + } + ++/** ++ * Called if a timeout for one group is reached. ++ * Sends a report for this group. ++ * ++ * @param group an mld_group for which a timeout is reached ++ */ ++static void ++mld6_timeout(struct netif *netif, struct mld_group *group) ++{ ++ /* If the state is MLD6_GROUP_DELAYING_MEMBER then we send a report for this group */ ++ if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) { ++ LWIP_DEBUGF(MLD6_DEBUG, ("mld6_timeout: report membership for group with address ")); ++ ip6_addr_debug_print_val(MLD6_DEBUG, group->group_address); ++ LWIP_DEBUGF(MLD6_DEBUG, (" on if %p\n", (void *)netif)); ++ ++ group->group_state = MLD6_GROUP_IDLE_MEMBER; ++ ++ MLD6_STATS_INC(mld6.tx_report); ++ mld6_send(netif, group, ICMP6_TYPE_MLR); ++ } ++} ++ ++#if LWIP_IPV6_MLD_V2 ++/** ++ * Called if a timeout for one group is reached. ++ * Sends a report for this group. ++ * ++ * @param group an mld_group for which a timeout is reached ++ */ ++static void ++mld6_v2_timeout(struct netif *netif, struct mld_group *group) ++{ ++ /* If the state is MLD6_GROUP_DELAYING_MEMBER then we send a report for this group */ ++ if (group->v2_group_state == MLD6_GROUP_DELAYING_MEMBER) { ++ LWIP_DEBUGF(MLD6_DEBUG, ("mld6_v2_timeout: report membership for group with address ")); ++ ip6_addr_debug_print_val(MLD6_DEBUG, group->group_address); ++ LWIP_DEBUGF(MLD6_DEBUG, (" on if %p\n", (void *)netif)); ++ ++ group->v2_group_state = MLD6_GROUP_IDLE_MEMBER; ++ ++ MLD6_STATS_INC(mld6.tx_report); ++ mld6_v2_send(netif, group, ICMP6_TYPE_MLR2); ++ } ++} ++#endif /* LWIP_IPV6_MLD_V2 */ + + /** + * Periodic timer for mld processing. Must be called every +@@ -504,14 +632,17 @@ mld6_tmr(void) + if (group->timer > 0) { + group->timer--; + if (group->timer == 0) { +- /* If the state is MLD6_GROUP_DELAYING_MEMBER then we send a report for this group */ +- if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) { +- MLD6_STATS_INC(mld6.tx_report); +- mld6_send(netif, group, ICMP6_TYPE_MLR); +- group->group_state = MLD6_GROUP_IDLE_MEMBER; +- } ++ mld6_timeout(netif, group); ++ } ++ } ++#if LWIP_IPV6_MLD_V2 ++ if (group->v2_timer > 0) { ++ group->v2_timer--; ++ if (group->v2_timer == 0) { ++ mld6_v2_timeout(netif, group); + } + } ++#endif + group = group->next; + } + } +@@ -550,6 +681,46 @@ mld6_delayed_report(struct mld_group *group, u16_t maxresp_in) + } + } + ++#if LWIP_IPV6_MLD_V2 ++/** ++ * Schedule a delayed membership report for a group ++ * ++ * @param group the mld_group for which "delaying" membership report ++ * should be sent ++ * @param maxresp_in the max resp delay provided in the query ++ */ ++static void ++mld6_v2_delayed_report(struct mld_group *group, u16_t maxresp_in) ++{ ++ /* Convert maxresp from milliseconds to tmr ticks */ ++ u16_t maxresp = maxresp_in / MLD6_TMR_INTERVAL; ++ if (maxresp >= 32768) { ++ maxresp = ((maxresp & 0x0fff) | 0x1000) << (((maxresp >> 12) & 7) + 3);; ++ } ++ if (maxresp == 0) { ++ maxresp = 1; ++ } ++ ++#ifdef LWIP_RAND ++ /* Randomize maxresp. (if LWIP_RAND is supported) */ ++ maxresp = (u16_t)(LWIP_RAND() % maxresp); ++ if (maxresp == 0) { ++ maxresp = 1; ++ } ++#endif /* LWIP_RAND */ ++ ++ /* Apply timer value if no report has been scheduled already. */ ++ if ((group->v2_group_state == MLD6_GROUP_IDLE_MEMBER) || ++ ((group->v2_group_state == MLD6_GROUP_DELAYING_MEMBER) && ++ ((group->v2_timer == 0) || (maxresp < group->v2_timer)))) { ++ group->v2_timer = maxresp; ++ group->v2_group_state = MLD6_GROUP_DELAYING_MEMBER; ++ } ++} ++ ++#endif ++ ++ + /** + * Send a MLD message (report or done). + * +@@ -623,4 +794,181 @@ mld6_send(struct netif *netif, struct mld_group *group, u8_t type) + pbuf_free(p); + } + ++#if LWIP_IPV6_MLD_V2 ++/** ++ * Build a mld v2 record to a specific group. ++ * ++ * @param rec record to build ++ * @param group the group to which to send the packet ++ * @param fmode filter mode ++ * @param src_array source addr array ++ * @param src_cnt source addr cnt ++ */ ++static void ++mld_v2_build_record(struct mld_v2_record *rec, struct mld_group *group, u8_t fmode, ip6_addr_p_t *src_array, u32_t src_cnt) ++{ ++ ip6_addr_p_t *src_copy; ++ ++ if (fmode == MCAST_EXCLUDE) { ++ if (group->v2_fmode != MCAST_EXCLUDE) { ++ group->v2_fmode = MCAST_EXCLUDE; ++ rec->type = MLD2_CHANGE_TO_EXCLUDE; ++ } else { ++ rec->type = MLD2_MODE_IS_EXCLUDE; ++ } ++ ++ } else { ++ if (group->v2_fmode != MCAST_INCLUDE) { ++ group->v2_fmode = MCAST_INCLUDE; ++ rec->type = MLD2_CHANGE_TO_INCLUDE; ++ } else { ++ rec->type = MLD2_MODE_IS_INCLUDE; ++ } ++ } ++ ++ rec->aux_len = 0; ++ rec->src_num = PP_HTONS(src_cnt); ++ ip6_addr_copy_to_packed(rec->multicast_address, group->group_address); ++ ++ if (src_cnt) { ++ src_copy = (ip6_addr_p_t *)(rec + 1); ++ MEMCPY(src_copy, src_array, (src_cnt << 4)); ++ } ++} ++ ++/** ++ * Send a MLD message (report). ++ * ++ * An IPv6 hop-by-hop options header with a router alert option ++ * is prepended. ++ * ++ * @param group the group to report or quit ++ * @param type ICMP6_TYPE_MLR (report) or ICMP6_TYPE_MLD (done) ++ */ ++static void ++mld6_v2_send(struct netif *netif, struct mld_group *group, u8_t type) ++{ ++ struct mld_v2_report *mld_hdr; ++ struct mld_v2_record *rec; ++ struct pbuf *p; ++ const ip6_addr_t *src_addr; ++ ++ /* Select our source address. */ ++ if (!ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) { ++ /* This is a special case, when we are performing duplicate address detection. ++ * We must join the multicast group, but we don't have a valid address yet. */ ++ src_addr = IP6_ADDR_ANY6; ++ } else { ++ /* Use link-local address as source address. */ ++ src_addr = netif_ip6_addr(netif, 0); ++ } ++ ++ if (ICMP6_TYPE_MLD == type) { ++ p = pbuf_alloc(PBUF_IP, MLD_V2_REPORT_HLEN + MLD_V2_RECORD_LEN(0) + MLD6_HBH_HLEN, PBUF_RAM); ++ if (p == NULL) { ++ LWIP_DEBUGF(MLD6_DEBUG, ("mld6_v2_send: not enough memory for mld6_v2_send\n")); ++ IGMP_STATS_INC(mld6.memerr); ++ return; ++ } ++ ++ /* Move to make room for Hop-by-hop options header. */ ++ if (pbuf_remove_header(p, MLD6_HBH_HLEN)) { ++ pbuf_free(p); ++ MLD6_STATS_INC(mld6.lenerr); ++ return; ++ } ++ ++ mld_hdr = (struct mld_v2_report *)p->payload; ++ mld_hdr->type = ICMP6_TYPE_MLR2; ++ mld_hdr->reserved1 = 0; ++ mld_hdr->chksum = 0; ++ mld_hdr->reserved2 = 0; ++ mld_hdr->mrec_num = PP_HTONS(1); ++ ++ rec = (struct mld_v2_record *)(mld_hdr + 1); ++ if (group->v2_fmode == MCAST_EXCLUDE) { ++ rec->type = MLD2_CHANGE_TO_INCLUDE; ++ } else { ++ rec->type = MLD2_MODE_IS_INCLUDE; ++ } ++ rec->aux_len = 0; ++ rec->src_num = 0; /* IS_IN (NULL) mean drop group */ ++ ip6_addr_copy_to_packed(rec->multicast_address, group->group_address); ++ } else {/* Report a group */ ++ ip6_addr_p_t src_array[LWIP_MCAST_SRC_TBL_SIZE]; ++ u16_t src_cnt; ++ u8_t fmode; ++ ++ src_cnt = mcast_ip6_filter_info(netif, &group->group_address, src_array, LWIP_MCAST_SRC_TBL_SIZE, &fmode); ++ LWIP_ASSERT("mld6_v2_send: multicast filter error!", !(!src_cnt && (fmode == MCAST_INCLUDE))); ++ ++ p = pbuf_alloc(PBUF_IP, MLD_V2_REPORT_HLEN + MLD_V2_RECORD_LEN(src_cnt) + MLD6_HBH_HLEN, PBUF_RAM); ++ if (p == NULL) { ++ LWIP_DEBUGF(MLD6_DEBUG, ("mld6_v2_send: not enough memory for mld6_v2_send\n")); ++ IGMP_STATS_INC(mld6.memerr); ++ return; ++ } ++ ++ mld_hdr = (struct mld_v2_report *)p->payload; ++ mld_hdr->type = ICMP6_TYPE_MLR2; ++ mld_hdr->reserved1 = 0; ++ mld_hdr->chksum = 0; ++ mld_hdr->reserved2 = 0; ++ mld_hdr->mrec_num = PP_HTONS(1); ++ ++ rec = (struct mld_v2_record *)(mld_hdr + 1); ++ mld_v2_build_record(rec, group, fmode, src_array, src_cnt); ++ group->v2_last_reporter_flag = 1;/* Remember we were the last to report */ ++ } ++ ++ #if CHECKSUM_GEN_ICMP6 ++ IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { ++ mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, ++ src_addr, &(group->group_address)); ++ } ++#endif /* CHECKSUM_GEN_ICMP6 */ ++ ++ /* Add hop-by-hop headers options: router alert with MLD value. */ ++ ip6_options_add_hbh_ra(p, IP6_NEXTH_ICMP6, IP6_ROUTER_ALERT_VALUE_MLD); ++ ++ /* Send the packet out. */ ++ MLD6_STATS_INC(mld6.xmit); ++ ip6_output_if(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address), ++ MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, netif); ++ pbuf_free(p); ++} ++ ++/** ++ * mld v2 report trigger. ++ */ ++void ++mld6_v2_trigger(struct netif *netif, const ip6_addr_t *groupaddr) ++{ ++ struct mld_group *group; ++#if LWIP_IPV6_SCOPES ++ ip6_addr_t ip6addr; ++ ++ /* If the address has a particular scope but no zone set, use the netif to ++ * set one now. Within the mld6 module, all addresses are properly zoned. */ ++ if (ip6_addr_lacks_zone(groupaddr, IP6_MULTICAST)) { ++ ip6_addr_set(&ip6addr, groupaddr); ++ ip6_addr_assign_zone(&ip6addr, IP6_MULTICAST, netif); ++ groupaddr = &ip6addr; ++ } ++ IP6_ADDR_ZONECHECK_NETIF(groupaddr, netif); ++#endif /* LWIP_IPV6_SCOPES */ ++ ++ /* find group */ ++ group = mld6_lookfor_group(netif, groupaddr); ++ if (group) { ++ mld6_v2_send(netif, group, ICMP6_TYPE_MLR2); ++ ++ mld6_v2_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); ++ ++ /* Need to work out where this timer comes from */ ++ group->v2_group_state = MLD6_GROUP_DELAYING_MEMBER; ++ } ++} ++#endif ++ + #endif /* LWIP_IPV6 */ +diff --git a/src/core/mcast.c b/src/core/mcast.c +index 5e3463b..fa46f10 100644 +--- a/src/core/mcast.c ++++ b/src/core/mcast.c +@@ -250,6 +250,204 @@ mcast_ip4_filter_interest(struct netif *netif, const ip4_addr_t *multi_addr, con + #endif /* LWIP_IGMP_V3 */ + #endif /* LWIP_IPV4 && LWIP_IGMP */ + ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++/** ++ * ipv6 multicast filter find ++ */ ++struct ip6_mc * ++mcast_ip6_mc_find(struct ip_mc *ipmc, struct netif *netif, const ip6_addr_t *multi_addr, struct ip6_mc **mc_prev) ++{ ++ struct ip6_mc *prev = NULL; ++ struct ip6_mc *mc; ++ ++ IP6_MC_FOREACH(ipmc, mc) { ++ if (((mc->if_idx == NETIF_NO_INDEX) || (mc->if_idx == netif_get_index(netif))) && ++ ip6_addr_cmp_zoneless(&mc->multi_addr, multi_addr)) { /* check interface and multicast address */ ++ if (mc_prev) { ++ *mc_prev = prev; ++ } ++ return mc; /* found! */ ++ } ++ prev = mc; ++ } ++ ++ return NULL; /* not found! */ ++} ++ ++/** ++ * ipv6 multicast filter find source ++ */ ++static struct mld6_src * ++mcast_ip6_mc_src_find(struct ip6_mc *mc, const ip6_addr_t *src_addr, struct mld6_src **src_prev) ++{ ++ struct mld6_src *prev = NULL; ++ struct mld6_src *src; ++ ++ IP6_MC_SRC_FOREACH(mc, src) { ++ if (ip6_addr_cmp_zoneless(&src->src_addr, src_addr)) { /* check source address */ ++ if (src_prev) { ++ *src_prev = prev; ++ } ++ return src; /* found! */ ++ } ++ prev = src; ++ } ++ ++ return NULL; /* not found! */ ++} ++ ++/** ++ * ipv6 multicast filter remove all source ++ */ ++void ++mcast_ip6_mc_src_remove(struct mld6_src *src) ++{ ++ struct mld6_src *next; ++ ++ while (src) { ++ next = src->next; ++ mem_free(src); ++ src = next; ++ } ++} ++ ++#if LWIP_IPV6_MLD_V2 ++/** ++ * ipv6 multicast filter group source infomation (use ip6_addr_p_t for MLDv2 speedup) ++ */ ++u16_t ++mcast_ip6_filter_info(struct netif *netif, const ip6_addr_t *multi_addr, ip6_addr_p_t addr_array[], u16_t arr_cnt, u8_t *fmode) ++{ ++ static ip6_addr_p_t in_tbl[LWIP_MCAST_SRC_TBL_SIZE]; ++ static ip6_addr_p_t ex_tbl[LWIP_MCAST_SRC_TBL_SIZE]; ++ ++ struct ip6_mc *mc; ++ struct mld6_src *src; ++ ip6_addr_t addr; /* for compare speed */ ++ u16_t i, j; ++ u16_t cnt, in_cnt = 0, ex_cnt = 0; ++ u16_t max_cnt = (u16_t)((arr_cnt > LWIP_MCAST_SRC_TBL_SIZE) ? LWIP_MCAST_SRC_TBL_SIZE : arr_cnt); ++ u8_t match = 0; ++ ++#define LWIP_IP6_MC_GET(pcb, pcbs, type, tbl, c) \ ++ for ((pcb) = (pcbs); (pcb) != NULL; (pcb) = (pcb)->next) { \ ++ mc = mcast_ip6_mc_find(&(pcb)->ipmc, netif, multi_addr, NULL); \ ++ if ((mc == NULL) || (mc->fmode != (type))) { \ ++ continue; \ ++ } \ ++ match = 1; \ ++ IP6_MC_SRC_FOREACH(mc, src) { \ ++ if ((c) < max_cnt) { \ ++ ip6_addr_copy_to_packed((tbl)[(c)], src->src_addr); /* save a source */ \ ++ (c)++; \ ++ } else { \ ++ *fmode = MCAST_EXCLUDE; /* table overflow, we need all this group packet */ \ ++ return (0); \ ++ } \ ++ } \ ++ } ++ ++#if LWIP_UDP ++ { ++ struct udp_pcb *pcb; ++ LWIP_IP6_MC_GET(pcb, udp_pcbs, MCAST_INCLUDE, in_tbl, in_cnt); /* copy all udp include source address to in_tbl[] */ ++ } ++#endif /* LWIP_UDP */ ++ ++#if LWIP_RAW ++ { ++ struct raw_pcb *pcb; ++ LWIP_IP6_MC_GET(pcb, raw_pcbs, MCAST_INCLUDE, in_tbl, in_cnt); /* copy all raw include source address to in_tbl[] */ ++ } ++#endif /* LWIP_UDP */ ++ ++#if LWIP_UDP ++ { ++ struct udp_pcb *pcb; ++ LWIP_IP6_MC_GET(pcb, udp_pcbs, MCAST_EXCLUDE, ex_tbl, ex_cnt); /* copy all udp exclude source address to ex_tbl[] */ ++ } ++#endif /* LWIP_UDP */ ++ ++#if LWIP_RAW ++ { ++ struct raw_pcb *pcb; ++ LWIP_IP6_MC_GET(pcb, raw_pcbs, MCAST_EXCLUDE, ex_tbl, ex_cnt); /* copy all raw exclude source address to ex_tbl[] */ ++ } ++#endif /* LWIP_UDP */ ++ ++ if (ex_cnt) { /* at least have one exclude source address */ ++ *fmode = MCAST_EXCLUDE; ++ for (i = 0; i < ex_cnt; i++) { ++ ip6_addr_copy_from_packed(addr, ex_tbl[i]); ++ for (j = 0; j < in_cnt; j++) { ++ if (ip6_addr_cmp_zoneless(&addr, &in_tbl[j])) { /* check exclude conflict with include table */ ++ ip6_addr_copy_to_packed(ex_tbl[i], *IP6_ADDR_ANY6); /* remove from exclude table */ ++ break; ++ } ++ } ++ } ++ ++ for (i = 0, cnt = 0; i < ex_cnt; i++) { ++ if (!ip6_addr_isany(&ex_tbl[i])) { ++ ip6_addr_copy_to_packed(addr_array[cnt], ex_tbl[i]); ++ cnt++; ++ } ++ } ++ ++ } else if (in_cnt) { /* at least have one include source address */ ++ *fmode = MCAST_INCLUDE; ++ for (i = 0; i < in_cnt; i++) { ++ ip6_addr_copy_to_packed(addr_array[i], in_tbl[i]); ++ } ++ cnt = i; ++ ++ } else { ++ if (match) { /* at least have one pcb matched */ ++ *fmode = MCAST_EXCLUDE; ++ } else { /* no match! */ ++ *fmode = MCAST_INCLUDE; ++ } ++ cnt = 0; ++ } ++ ++ return (cnt); ++} ++ ++/** ++ * ipv6 multicast filter source address interest (use ip6_addr_p_t for MLDv2 speedup) ++ */ ++u8_t ++mcast_ip6_filter_interest(struct netif *netif, const ip6_addr_t *multi_addr, const ip6_addr_p_t src_addr[], u16_t arr_cnt) ++{ ++ static ip6_addr_p_t ip_tbl[LWIP_MCAST_SRC_TBL_SIZE]; ++ u16_t i, j, cnt; ++ u8_t fmode; ++ ++ cnt = mcast_ip6_filter_info(netif, multi_addr, ip_tbl, LWIP_MCAST_SRC_TBL_SIZE, &fmode); ++ if (fmode == MCAST_EXCLUDE) { ++ for (i = 0; i < cnt; i++) { ++ for (j = 0; j < arr_cnt; j++) { ++ if (ip6_addr_cmp_zoneless(&src_addr[j], &ip_tbl[i])) { ++ return 0; ++ } ++ } ++ } ++ return 1; ++ ++ } else { ++ for (i = 0; i < cnt; i++) { ++ for (j = 0; j < arr_cnt; j++) { ++ if (ip6_addr_cmp_zoneless(&src_addr[j], &ip_tbl[i])) { ++ return 1; ++ } ++ } ++ } ++ return 0; ++ } ++} ++#endif /* LWIP_IPV6_MLD_V2 */ ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ ++ + #if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) + /** Join a multicast group (Can with a source specified) + * +@@ -303,8 +501,9 @@ mcast_join_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi + mc->src = src; + mc->fmode = MCAST_INCLUDE; /* change to include mode */ + IP4_MC_TRIGGER_CALL(netif, ip_2_ip4(multi_addr)); /* trigger a report */ ++ return ERR_OK; + } +- return ERR_OK; ++ return EADDRINUSE; + } + + mc = (struct ip4_mc *)mem_malloc(sizeof(struct ip4_mc)); /* Make a new mc */ +@@ -334,8 +533,68 @@ mcast_join_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi + mc->next = ipmc->mc4; + ipmc->mc4 = mc; + igmp_joingroup_netif(netif, ip_2_ip4(multi_addr)); +- } else {} ++ } else + #endif /* LWIP_IPV4 && LWIP_IGMP */ ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ struct ip6_mc *mc; ++ struct mld6_src *src; ++ ++ mc = mcast_ip6_mc_find(ipmc, netif, ip_2_ip6(multi_addr), NULL); ++ if (mc) { ++ if (src_addr) { ++ if ((mc->fmode == MCAST_EXCLUDE) && (mc->src)) { ++ return ERR_VAL; /* filter mode not include mode */ ++ } ++ src = mcast_ip6_mc_src_find(mc, ip_2_ip6(src_addr), NULL); ++ if (src) { ++ return ERR_ALREADY; /* already in source list */ ++ } ++ ++ src = (struct mld6_src *)mem_malloc(sizeof(struct mld6_src)); ++ if (src == NULL) { ++ return ERR_MEM; /* no memory */ ++ } ++ ip6_addr_set(&src->src_addr, ip_2_ip6(src_addr)); ++ src->next = mc->src; ++ mc->src = src; ++ mc->fmode = MCAST_INCLUDE; /* change to include mode */ ++ IP6_MC_TRIGGER_CALL(netif, ip_2_ip6(multi_addr)); /* trigger a report */ ++ return ERR_OK; ++ } ++ return EADDRINUSE; ++ } ++ ++ mc = (struct ip6_mc *)mem_malloc(sizeof(struct ip6_mc)); /* Make a new mc */ ++ if (mc == NULL) { ++ mld6_leavegroup_netif(netif, ip_2_ip6(multi_addr)); ++ return ERR_MEM; /* no memory */ ++ } ++ mc->if_idx = netif_get_index(netif); ++ ip6_addr_set(&mc->multi_addr, ip_2_ip6(multi_addr)); ++ ++ if (src_addr) { ++ mc->fmode = MCAST_INCLUDE; ++ src = (struct mld6_src *)mem_malloc(sizeof(struct mld6_src)); ++ if (src == NULL) { ++ mld6_leavegroup_netif(netif, ip_2_ip6(multi_addr)); ++ mem_free(mc); ++ return ERR_MEM; /* no memory */ ++ } ++ ip6_addr_set(&src->src_addr, ip_2_ip6(src_addr)); ++ src->next = NULL; ++ mc->src = src; ++ ++ } else { ++ mc->fmode = MCAST_EXCLUDE; /* no source specified */ ++ mc->src = NULL; ++ } ++ ++ mc->next = ipmc->mc6; ++ ipmc->mc6 = mc; ++ mld6_joingroup_netif(netif, ip_2_ip6(multi_addr)); ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ ++ } + return ERR_OK; + } + +@@ -364,8 +623,23 @@ mcast_join_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const ip_addr_t * + } + } + } +- } else {} ++ } else + #endif /* LWIP_IPV4 && LWIP_IGMP */ ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ struct netif *netif; ++ ++ NETIF_FOREACH(netif) { ++ if (ip6_addr_isany(ip_2_ip6(if_addr)) || ++ netif_get_ip6_addr_match(netif, ip_2_ip6(if_addr)) >= 0) { ++ err = mcast_join_netif(ipmc, netif, multi_addr, src_addr); ++ if (err != ERR_OK) { ++ return (err); ++ } ++ } ++ } ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ ++ } + return err; + } + +@@ -423,8 +697,53 @@ mcast_leave_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *mult + ipmc->mc4 = mc->next; + } + mem_free(mc); +- } else {} ++ } else + #endif /* LWIP_IPV4 && LWIP_IGMP */ ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ struct ip6_mc *mc_prev; ++ struct ip6_mc *mc; ++ struct mld6_src *src_prev; ++ struct mld6_src *src; ++ ++ mc = mcast_ip6_mc_find(ipmc, netif, ip_2_ip6(multi_addr), &mc_prev); ++ if (mc == NULL) { ++ return ERR_VAL; ++ } ++ ++ if (src_addr) { ++ if ((mc->fmode == MCAST_EXCLUDE) && (mc->src)) { ++ return ERR_VAL; /* drop source membership must in include mode */ ++ } ++ ++ src = mcast_ip6_mc_src_find(mc, ip_2_ip6(src_addr), &src_prev); ++ if (src) { ++ if (src_prev) { ++ src_prev->next = src->next; ++ } else { ++ mc->src = src->next; ++ } ++ mem_free(src); ++ } else { ++ return ERR_VAL; ++ } ++ if (mc->src) { ++ IP6_MC_TRIGGER_CALL(netif, ip_2_ip6(multi_addr)); /* trigger a report */ ++ return ERR_OK; ++ } ++ } else { /* we want drop this group */ ++ mcast_ip6_mc_src_remove(mc->src); ++ } ++ ++ mld6_leavegroup_netif(netif, ip_2_ip6(multi_addr)); ++ if (mc_prev) { ++ mc_prev->next = mc->next; ++ } else { ++ ipmc->mc6 = mc->next; ++ } ++ mem_free(mc); ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ ++ } + return ERR_OK; + } + +@@ -453,8 +772,23 @@ mcast_leave_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const ip_addr_t + } + } + } +- } else {} ++ } else + #endif /* LWIP_IPV4 && LWIP_IGMP */ ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ struct netif *netif; ++ ++ NETIF_FOREACH(netif) { ++ if (ip6_addr_isany(ip_2_ip6(if_addr)) || ++ netif_get_ip6_addr_match(netif, ip_2_ip6(if_addr)) >= 0) { ++ res = mcast_leave_netif(ipmc, netif, multi_addr, src_addr); ++ if (err != ERR_OK) { ++ err = res; ++ } ++ } ++ } ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ ++ } + return err; + } + +@@ -492,11 +826,36 @@ mcast_block_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *mult + src->next = mc->src; + mc->src = src; + IP4_MC_TRIGGER_CALL(netif, ip_2_ip4(multi_addr)); /* trigger a report */ +- return ERR_OK; + } +- } else {} ++ } else + #endif /* LWIP_IPV4 && LWIP_IGMP */ +- return EADDRINUSE; ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ struct ip6_mc *mc; ++ struct mld6_src *src; ++ ++ mc = mcast_ip6_mc_find(ipmc, netif, ip_2_ip6(multi_addr), NULL); ++ if (mc == NULL) { ++ return ERR_VAL; ++ } ++ if (mc->fmode != MCAST_EXCLUDE) { /* we must in exclude mode */ ++ return ERR_VAL; ++ } ++ ++ src = mcast_ip6_mc_src_find(mc, ip_2_ip6(blk_addr), NULL); ++ if (src == NULL) { ++ src = (struct mld6_src *)mem_malloc(sizeof(struct mld6_src)); ++ if (src == NULL) { ++ return ERR_MEM; ++ } ++ ip6_addr_set(&src->src_addr, ip_2_ip6(blk_addr)); ++ src->next = mc->src; ++ mc->src = src; ++ IP6_MC_TRIGGER_CALL(netif, ip_2_ip6(multi_addr)); /* trigger a report */ ++ } ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ ++ } ++ return ERR_OK; + } + + /** Add a block source address to a multicast group +@@ -524,8 +883,23 @@ mcast_block_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const ip_addr_t + } + } + } +- } else {} ++ } else + #endif /* LWIP_IPV4 && LWIP_IGMP */ ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ struct netif *netif; ++ ++ NETIF_FOREACH(netif) { ++ if (ip6_addr_isany(ip_2_ip6(if_addr)) || ++ netif_get_ip6_addr_match(netif, ip_2_ip6(if_addr)) >= 0) { ++ err = mcast_block_netif(ipmc, netif, multi_addr, blk_addr); ++ if (err != ERR_OK) { ++ return (err); ++ } ++ } ++ } ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ ++ } + return err; + } + +@@ -565,8 +939,35 @@ mcast_unblock_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *mu + } + mem_free(src); + IP4_MC_TRIGGER_CALL(netif, ip_2_ip4(multi_addr)); /* trigger a report */ +- } else {} ++ } else + #endif /* LWIP_IPV4 && LWIP_IGMP */ ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ struct ip6_mc *mc; ++ struct mld6_src *src_prev; ++ struct mld6_src *src; ++ ++ mc = mcast_ip6_mc_find(ipmc, netif, ip_2_ip6(multi_addr), NULL); ++ if (mc == NULL) { ++ return ERR_VAL; ++ } ++ if (mc->fmode != MCAST_EXCLUDE) { /* we must in exclude mode */ ++ return ERR_VAL; ++ } ++ ++ src = mcast_ip6_mc_src_find(mc, ip_2_ip6(unblk_addr), &src_prev); ++ if (src == NULL) { ++ return ERR_VAL; ++ } ++ if (src_prev) { ++ src_prev->next = src->next; ++ } else { ++ mc->src = src->next; ++ } ++ mem_free(src); ++ IP6_MC_TRIGGER_CALL(netif, ip_2_ip6(multi_addr)); /* trigger a report */ ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ ++ } + return ERR_OK; + } + +@@ -595,8 +996,23 @@ mcast_unblock_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const ip_addr_ + } + } + } +- } else {} ++ } else + #endif /* LWIP_IPV4 && LWIP_IGMP */ ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ struct netif *netif; ++ ++ NETIF_FOREACH(netif) { ++ if (ip6_addr_isany(ip_2_ip6(if_addr)) || ++ netif_get_ip6_addr_match(netif, ip_2_ip6(if_addr)) >= 0) { ++ res = mcast_unblock_netif(ipmc, netif, multi_addr, unblk_addr); ++ if (err != ERR_OK) { ++ err = res; ++ } ++ } ++ } ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ ++ } + return err; + } + +diff --git a/src/core/udp.c b/src/core/udp.c +index e1f9e1b..4a47e99 100644 +--- a/src/core/udp.c ++++ b/src/core/udp.c +@@ -195,6 +195,12 @@ udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast) + return 0; + } + ++#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++ if (ip_addr_ismulticast(ip_current_dest_addr())) { ++ return mcast_input_local_match(&pcb->ipmc, inp); ++ } ++#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ ++ + /* Dual-stack: PCBs listening to any IP type also listen to any IP address */ + if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { + #if LWIP_IPV4 && IP_SOF_BROADCAST_RECV +@@ -205,12 +211,6 @@ udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast) + return 1; + } + +-#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) +- if (ip_addr_ismulticast(ip_current_dest_addr())) { +- return mcast_input_local_match(&pcb->ipmc, inp); +- } +-#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ +- + /* Only need to check PCB if incoming IP version matches PCB IP version */ + if (IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) { + #if LWIP_IPV4 +diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h +index d5783dd..319ee09 100644 +--- a/src/include/lwip/api.h ++++ b/src/include/lwip/api.h +@@ -103,6 +103,7 @@ extern "C" { + #define NETCONNTYPE_ISIPV6(t) (((t)&NETCONN_TYPE_IPV6) != 0) + #define NETCONNTYPE_ISUDPLITE(t) (((t)&0xF3) == NETCONN_UDPLITE) + #define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF3) == NETCONN_UDPNOCHKSUM) ++#define NETCONNTYPE_GROUPV6(t) ((t)&0xFF) + #else /* LWIP_IPV6 */ + #define NETCONNTYPE_ISIPV6(t) (0) + #define NETCONNTYPE_ISUDPLITE(t) ((t) == NETCONN_UDPLITE) +diff --git a/src/include/lwip/mcast.h b/src/include/lwip/mcast.h +index c7b195d..16a27ae 100644 +--- a/src/include/lwip/mcast.h ++++ b/src/include/lwip/mcast.h +@@ -74,6 +74,28 @@ struct ip4_mc { + #endif /* LWIP_IPV4 && LWIP_IGMP */ + + ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++/** the IPv6 multicast filter */ ++struct ip6_mc { ++ struct ip6_mc *next; ++ /** the interface index */ ++ u8_t if_idx; ++ /** the group address */ ++ ip6_addr_t multi_addr; ++ /** the source address list filter mode 0: EXCLUDE 1: INCLUDE */ ++ u8_t fmode; ++ /** the source address list */ ++ struct mld6_src *src; ++}; ++ ++/** The list of ip6_mc. */ ++#define IP6_MC_FOREACH(ipmc, mc) \ ++ for ((mc) = (ipmc)->mc6; (mc) != NULL; (mc) = (mc)->next) ++#define IP6_MC_SRC_FOREACH(mc, src) \ ++ for ((src) = (mc)->src; (src) != NULL; (src) = (src)->next) ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ ++ ++ + #if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) + /* multicast filter control block */ + struct ip_mc { +@@ -85,6 +107,10 @@ struct ip_mc { + #if LWIP_IPV4 && LWIP_IGMP + struct ip4_mc *mc4; + #endif /* LWIP_IPV4 && LWIP_IGMP */ ++ ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ struct ip6_mc *mc6; ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ + }; + + #if LWIP_IPV4 && LWIP_IGMP && LWIP_IGMP_V3 +@@ -93,6 +119,13 @@ u16_t mcast_ip4_filter_info(struct netif *netif, const ip4_addr_t *multi_addr, + u8_t mcast_ip4_filter_interest(struct netif *netif, const ip4_addr_t *multi_addr, const ip4_addr_p_t src_addr[], u16_t arr_cnt); + #endif /* LWIP_IPV4 && LWIP_IGMP && LWIP_IGMP_V3 */ + ++#if LWIP_IPV6 && LWIP_IPV6_MLD && LWIP_IPV6_MLD_V2 ++/* MLDv2 use the following function to get specified group of total multicast filter source address array */ ++u16_t mcast_ip6_filter_info(struct netif *netif, const ip6_addr_t *multi_addr, ip6_addr_p_t addr_array[], u16_t arr_cnt, u8_t *fmode); ++u8_t mcast_ip6_filter_interest(struct netif *netif, const ip6_addr_t *multi_addr, const ip6_addr_p_t src_addr[], u16_t arr_cnt); ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD && LWIP_IPV6_MLD_V2 */ ++ ++ + /* UDP or RAW use the following functions */ + void mcast_pcb_remove(struct ip_mc *ipmc); + u8_t mcast_input_local_match(struct ip_mc *ipmc, struct netif *inp); +@@ -109,6 +142,8 @@ err_t mcast_unblock_group(struct ip_mc *ipmc, const ip_addr_t *if_addr, const + + struct ip4_mc *mcast_ip4_mc_find(struct ip_mc *ipmc, struct netif *netif, const ip4_addr_t *multi_addr, struct ip4_mc **mc_prev); + void mcast_ip4_mc_src_remove(struct igmp_src *src); ++struct ip6_mc *mcast_ip6_mc_find(struct ip_mc *ipmc, struct netif *netif, const ip6_addr_t *multi_addr, struct ip6_mc **mc_prev); ++void mcast_ip6_mc_src_remove(struct mld6_src *src); + + #endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ + +diff --git a/src/include/lwip/mld6.h b/src/include/lwip/mld6.h +index 2764fdd..7819551 100644 +--- a/src/include/lwip/mld6.h ++++ b/src/include/lwip/mld6.h +@@ -54,6 +54,13 @@ + extern "C" { + #endif + ++/* Multicast filter support */ ++struct mld6_src { ++ struct mld6_src *next; ++ /** the source address */ ++ ip6_addr_t src_addr; ++}; ++ + /** MLD group */ + struct mld_group { + /** next link */ +@@ -68,6 +75,16 @@ struct mld_group { + u16_t timer; + /** counter of simultaneous uses */ + u8_t use; ++ #if LWIP_IPV6_MLD_V2 ++ /** Last report fmode */ ++ u8_t v2_fmode; ++ /** signifies we were the last person to report */ ++ u8_t v2_last_reporter_flag; ++ /** current state of the group */ ++ u8_t v2_group_state; ++ /** timer for reporting, negative is OFF */ ++ u16_t v2_timer; ++#endif /* LWIP_IPV6_MLD_V2 */ + }; + + #define MLD6_TMR_INTERVAL 100 /* Milliseconds */ +@@ -90,6 +107,19 @@ err_t mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr); + */ + #define netif_mld6_data(netif) ((struct mld_group *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6)) + ++/** ++ * ipv6 multicast filter trigger function ++ */ ++#if LWIP_IPV6_MLD_V2 ++ ++#define MLD6_FMODE_INIT 2 /* Not MCAST_INCLUDE or MCAST_EXCLUDE */ ++void mld6_v2_trigger(struct netif *netif, const ip6_addr_t *groupaddr); ++#define IP6_MC_TRIGGER_CALL(netif, multi_addr) mld6_v2_trigger(netif, multi_addr) ++#else ++#define IP6_MC_TRIGGER_CALL(netif, multi_addr) ++#endif /* !LWIP_IPV6_MLD_V2 */ ++ ++ + #ifdef __cplusplus + } + #endif +diff --git a/src/include/lwip/netbuf.h b/src/include/lwip/netbuf.h +index e32c9bd..e7f0713 100644 +--- a/src/include/lwip/netbuf.h ++++ b/src/include/lwip/netbuf.h +@@ -68,6 +68,9 @@ struct netbuf { + u16_t toport_chksum; + #if LWIP_NETBUF_RECVINFO + ip_addr_t toaddr; ++#if LWIP_IPV6 ++ u8_t hoplim; ++#endif /* LWIP_IPV6 */ + #endif /* LWIP_NETBUF_RECVINFO */ + #endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ + }; +diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h +index 06303f4..9a1a32d 100644 +--- a/src/include/lwip/opt.h ++++ b/src/include/lwip/opt.h +@@ -3584,6 +3584,14 @@ + #if !defined DHCP6_DEBUG || defined __DOXYGEN__ + #define DHCP6_DEBUG LWIP_DBG_OFF + #endif ++ ++/** ++ * MLD6_DEBUG: Enable debugging in mld6.c. ++ */ ++#if !defined MLD6_DEBUG || defined __DOXYGEN__ ++#define MLD6_DEBUG LWIP_DBG_OFF ++#endif ++ + /** + * @} + */ +diff --git a/src/include/lwip/prot/icmp6.h b/src/include/lwip/prot/icmp6.h +index 36989f6..17186b6 100644 +--- a/src/include/lwip/prot/icmp6.h ++++ b/src/include/lwip/prot/icmp6.h +@@ -70,6 +70,8 @@ enum icmp6_type { + ICMP6_TYPE_MLR = 131, + /** Multicast listener done */ + ICMP6_TYPE_MLD = 132, ++ /** Multicast listener report v2*/ ++ ICMP6_TYPE_MLR2 = 143, + /** Router solicitation */ + ICMP6_TYPE_RS = 133, + /** Router advertisement */ +diff --git a/src/include/lwip/prot/mld6.h b/src/include/lwip/prot/mld6.h +index 71f1dcb..40f1ca6 100644 +--- a/src/include/lwip/prot/mld6.h ++++ b/src/include/lwip/prot/mld6.h +@@ -64,6 +64,85 @@ PACK_STRUCT_END + # include "arch/epstruct.h" + #endif + ++#if LWIP_IPV6_MLD_V2 /* RFC 3810 */ ++/** ++ * MLDv2 query packet format. ++ */ ++#ifdef PACK_STRUCT_USE_INCLUDES ++# include "arch/bpstruct.h" ++#endif ++ PACK_STRUCT_BEGIN ++ struct mld_v2_query { ++ PACK_STRUCT_FLD_8(u8_t type); ++ PACK_STRUCT_FLD_8(u8_t code); ++ PACK_STRUCT_FIELD(u16_t chksum); ++ PACK_STRUCT_FIELD(u16_t max_resp_delay); ++ PACK_STRUCT_FIELD(u16_t reserved); ++ PACK_STRUCT_FLD_S(ip6_addr_t multicast_address); ++ PACK_STRUCT_FLD_8(u8_t resv_s_qrv); ++ PACK_STRUCT_FLD_8(u8_t qqic); ++ PACK_STRUCT_FIELD(u16_t src_num); ++ } PACK_STRUCT_STRUCT; ++ PACK_STRUCT_END ++#ifdef PACK_STRUCT_USE_INCLUDES ++# include "arch/epstruct.h" ++#endif ++ ++#define MLD_V2_QUERY_HLEN sizeof(struct mld_v2_query) ++ ++/** ++ * MLDv2 report packet header format. ++ */ ++#ifdef PACK_STRUCT_USE_INCLUDES ++# include "arch/bpstruct.h" ++#endif ++ PACK_STRUCT_BEGIN ++ struct mld_v2_report { ++ PACK_STRUCT_FLD_8(u8_t type); ++ PACK_STRUCT_FLD_8(u8_t reserved1); ++ PACK_STRUCT_FIELD(u16_t chksum); ++ PACK_STRUCT_FIELD(u16_t reserved2); ++ PACK_STRUCT_FIELD(u16_t mrec_num); ++ } PACK_STRUCT_STRUCT; ++ PACK_STRUCT_END ++#ifdef PACK_STRUCT_USE_INCLUDES ++# include "arch/epstruct.h" ++#endif ++ ++#define MLD_V2_REPORT_HLEN sizeof(struct mld_v2_report) ++ ++/* ++ * Definitions for MLDv2 ++ */ ++#define MLD2_MODE_IS_INCLUDE 1 ++#define MLD2_MODE_IS_EXCLUDE 2 ++#define MLD2_CHANGE_TO_INCLUDE 3 ++#define MLD2_CHANGE_TO_EXCLUDE 4 ++#define MLD2_ALLOW_NEW_SOURCES 5 ++#define MLD2_BLOCK_OLD_SOURCES 6 ++ ++/** ++ * MLDv2 report packet group record format. ++ */ ++#ifdef PACK_STRUCT_USE_INCLUDES ++# include "arch/bpstruct.h" ++#endif ++ PACK_STRUCT_BEGIN ++ struct mld_v2_record { ++ PACK_STRUCT_FLD_8(u8_t type); ++ PACK_STRUCT_FLD_8(u8_t aux_len); ++ PACK_STRUCT_FIELD(u16_t src_num); ++ PACK_STRUCT_FLD_S(ip6_addr_p_t multicast_address); ++ } PACK_STRUCT_STRUCT; ++ PACK_STRUCT_END ++#ifdef PACK_STRUCT_USE_INCLUDES ++# include "arch/epstruct.h" ++#endif ++ ++#define MLD_V2_RECORD_LEN(src_cnt) (sizeof(struct mld_v2_record) + (src_cnt << 4)) ++#endif /* LWIP_IPV6_MLD_V2 */ ++ ++ + #ifdef __cplusplus + } + #endif +diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h +index 00aca53..f2a1b59 100644 +--- a/src/include/lwip/sockets.h ++++ b/src/include/lwip/sockets.h +@@ -114,8 +114,11 @@ struct sockaddr { + char sa_data[14]; + }; + ++#ifndef LWIP_IPV6_MLD_V2 + struct sockaddr_storage { ++#if !GAZELLE_ENABLE + u8_t s2_len; ++#endif + sa_family_t ss_family; + char s2_data1[2]; + u32_t s2_data2[3]; +@@ -123,6 +126,27 @@ struct sockaddr_storage { + u32_t s2_data3[3]; + #endif /* LWIP_IPV6 */ + }; ++#else ++#ifndef _SS_SIZE ++#define _SS_SIZE 128 ++#endif //_SS_SIZE ++#ifndef __SOCKADDR_COMMON_SIZE ++#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int)) ++#endif //__SOCKADDR_COMMON_SIZE ++#ifndef __ss_aligntype ++#define __ss_aligntype unsigned long int ++#endif //__ss_aligntype ++#ifndef _SS_PADSIZE ++#define _SS_PADSIZE \ ++ (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) ++#endif //_SS_PADSIZE ++struct sockaddr_storage ++ { ++ sa_family_t ss_family; /* Address family, etc. */ ++ char __ss_padding[_SS_PADSIZE]; ++ __ss_aligntype __ss_align; /* Force desired alignment. */ ++ }; ++#endif //LWIP_IPV6_MLD_V2 + + /* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED + to prevent this code from redefining it. */ +@@ -335,6 +359,11 @@ struct linger { + */ + #define IPV6_CHECKSUM 7 /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */ + #define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */ ++#define IPV6_RECVPKTINFO 49 /* Recv IPV6_PKTINFO message */ ++#define IPV6_PKTINFO 50 ++#define IPV6_RECVHOPLIMIT 51 /* Recv IPV6_HOPLIMIT message */ ++#define IPV6_HOPLIMIT 52 ++#define IPV6_MINHOPCNT 99 + #endif /* LWIP_IPV6 */ + + #if LWIP_UDP && LWIP_UDPLITE +@@ -369,13 +398,24 @@ struct in_pktinfo { + }; + #endif /* LWIP_IPV4 */ + ++#if LWIP_IPV6 ++struct in6_pktinfo { ++ struct in6_addr ipi6_addr; ++ int ipi6_ifindex; ++}; ++#endif /* LWIP_IPV6 */ ++ + #if LWIP_IPV6_MLD ++#define IPV6_UNICAST_HOPS 16 /* IPv6 ttl */ ++#define IPV6_MULTICAST_IF 17 /* Set mcast ifindex, (The argument is a pointer to an interface index) */ ++#define IPV6_MULTICAST_HOPS 18 /* IPv6 mcast ttl */ ++#define IPV6_MULTICAST_LOOP 19 /* Mcast loop */ + /* + * Options and types related to IPv6 multicast membership + */ +-#define IPV6_JOIN_GROUP 12 ++#define IPV6_JOIN_GROUP 20 + #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +-#define IPV6_LEAVE_GROUP 13 ++#define IPV6_LEAVE_GROUP 21 + #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP + + typedef struct ipv6_mreq { +@@ -807,6 +847,7 @@ int mcast_sock_block_unblock_source_group(struct ip_mc *ipmc, int optname, c + int mcast_sock_set_groupfilter(struct ip_mc *ipmc, int optname, const struct group_filter *gf); + int mcast_sock_get_groupfilter(struct ip_mc *ipmc, int optname, struct group_filter *gf, socklen_t *size); + ++int mcast_sock_ipv6_add_drop_membership(int s, struct ip_mc *ipmc, int optname, const struct ipv6_mreq *imr); + #endif /*(LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD)*/ + + const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size); +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index ab36688..396bcdf 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h +@@ -292,4 +292,9 @@ + */ + #define LWIP_IGMP_V3 1 + ++ /** ++ * LWIP_IPV6_MLD_V2==1: Enable multicast listener discovery protocol v2. ++ */ ++#define LWIP_IPV6_MLD_V2 1 ++ + #endif /* __LWIPOPTS_H__ */ +-- +2.25.1 + diff --git a/0123-opts-modify-MEMP_NUM_UDP_PCB.patch b/0123-opts-modify-MEMP_NUM_UDP_PCB.patch new file mode 100644 index 0000000..fb34e0c --- /dev/null +++ b/0123-opts-modify-MEMP_NUM_UDP_PCB.patch @@ -0,0 +1,22 @@ +From 226fbb87dcf266d165962f1d87f9c4c5d4ea8e2d Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Thu, 11 Apr 2024 15:07:47 +0800 +Subject: [PATCH] opts: modify MEMP_NUM_UDP_PCB + + +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index 62573f5..4655388 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h +@@ -192,7 +192,7 @@ + + #define UDP_HLEN 8 + +-#define MEMP_NUM_UDP_PCB 16 ++#define MEMP_NUM_UDP_PCB (GAZELLE_MAX_CLIENTS + GAZELLE_RESERVED_CLIENTS) + #define MEMP_NUM_IGMP_GROUP 16 + + #define DEFAULT_UDP_RECVMBOX_SIZE 4096 +-- +2.33.0 + diff --git a/0124-fix-udp-recv-memleak.patch b/0124-fix-udp-recv-memleak.patch new file mode 100644 index 0000000..565643c --- /dev/null +++ b/0124-fix-udp-recv-memleak.patch @@ -0,0 +1,24 @@ +From b80f4cd0b3d5ea5349599ef12dd13a0bedafb3b9 Mon Sep 17 00:00:00 2001 +From: compile_success <980965867@qq.com> +Date: Mon, 22 Apr 2024 15:11:21 +0000 +Subject: [PATCH] fix udp recv memleak + +--- + src/api/api_msg.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/api/api_msg.c b/src/api/api_msg.c +index f0a3e0b..9da4869 100644 +--- a/src/api/api_msg.c ++++ b/src/api/api_msg.c +@@ -286,6 +286,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, + p->port = port; + len = p->tot_len; + if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) { ++ pbuf_free(p); + return; + #else /* GAZELLE_UDP_ENABLE */ + err_t err; +-- +2.33.0 + diff --git a/0125-add-MCAST_JOIN_SOURCE_GROUP-to-setsockopt-for-mldv2.patch b/0125-add-MCAST_JOIN_SOURCE_GROUP-to-setsockopt-for-mldv2.patch new file mode 100644 index 0000000..ed1b118 --- /dev/null +++ b/0125-add-MCAST_JOIN_SOURCE_GROUP-to-setsockopt-for-mldv2.patch @@ -0,0 +1,124 @@ +From c822d404bae65db647d7c0ddec4647f8b0cce1e1 Mon Sep 17 00:00:00 2001 +From: wanfeng +Date: Tue, 16 Apr 2024 15:23:46 +0800 +Subject: [PATCH] add MCAST_JOIN_SOURCE_GROUP to setsockopt for mldv2 + +--- + src/api/sockets.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 94 insertions(+) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index 6b2f5ee..50fa335 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -3976,6 +3976,29 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ + } + } + break; ++ case MCAST_JOIN_SOURCE_GROUP: ++ case MCAST_LEAVE_SOURCE_GROUP: ++ LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, struct group_source_req); ++ if ((((const struct group_source_req *)optval)->gsr_group.ss_family != AF_INET6) || ++ (((const struct group_source_req *)optval)->gsr_source.ss_family != AF_INET6)) { ++ done_socket(sock); ++ return EINVAL; ++ } ++#if LWIP_UDP ++ if (NETCONNTYPE_GROUPV6(netconn_type(sock->conn)) == NETCONN_UDP_IPV6) { ++ err = mcast_sock_join_leave_source_group(s, &sock->conn->pcb.udp->ipmc, optname, (const struct group_source_req *)optval); ++ } else ++#endif /* LWIP_UDP */ ++#if LWIP_RAW ++ if (NETCONNTYPE_GROUPV6(netconn_type(sock->conn)) == NETCONN_RAW_IPV6) { ++ err = mcast_sock_join_leave_source_group(s, &sock->conn->pcb.raw->ipmc, optname, (const struct group_source_req *)optval); ++ } else ++#endif /* LWIP_RAW */ ++ { ++ done_socket(sock); ++ return ENOPROTOOPT; ++ } ++ break; + #endif /* LWIP_IPV6_MLD */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", +@@ -4869,6 +4892,77 @@ out: + return err_to_errno(err); + } + ++/** ++ * setsockopt() MCAST_JOIN_SOURCE_GROUP / MCAST_LEAVE_SOURCE_GROUP command ++ */ ++int ++mcast_sock_join_leave_source_group(int s, struct ip_mc *ipmc, int optname, const struct group_source_req *gsr) ++{ ++ struct netif *netif; ++ ip_addr_t multi_addr; ++ ip_addr_t src_addr; ++ err_t err; ++ u8_t if_idx; ++ ++ if (gsr->gsr_group.ss_family == AF_INET) { ++ inet_addr_to_ip4addr(ip_2_ip4(&multi_addr), &(((struct sockaddr_in *)&(gsr->gsr_group))->sin_addr)); ++ inet_addr_to_ip4addr(ip_2_ip4(&src_addr), &(((struct sockaddr_in *)&(gsr->gsr_source))->sin_addr)); ++ IP_SET_TYPE_VAL(multi_addr, IPADDR_TYPE_V4); ++ IP_SET_TYPE_VAL(src_addr, IPADDR_TYPE_V4); ++ if (!ip4_addr_ismulticast(ip_2_ip4(&multi_addr)) || ip4_addr_isany(ip_2_ip4(&src_addr))) { ++ return EADDRNOTAVAIL; ++ } ++ ++ } else if (gsr->gsr_group.ss_family == AF_INET6) { ++ inet6_addr_to_ip6addr(ip_2_ip6(&multi_addr), &(((struct sockaddr_in6 *)&(gsr->gsr_group))->sin6_addr)); ++ inet6_addr_to_ip6addr(ip_2_ip6(&src_addr), &(((struct sockaddr_in6 *)&(gsr->gsr_source))->sin6_addr)); ++ IP_SET_TYPE_VAL(multi_addr, IPADDR_TYPE_V6); ++ IP_SET_TYPE_VAL(src_addr, IPADDR_TYPE_V6); ++ if (!ip6_addr_ismulticast(ip_2_ip6(&multi_addr)) || ip6_addr_isany(ip_2_ip6(&src_addr))) { ++ return EADDRNOTAVAIL; ++ } ++ ++ } else { ++ return EADDRNOTAVAIL; ++ } ++ ++ if (gsr->gsr_interface) { ++ netif = netif_get_by_index((u8_t)gsr->gsr_interface); ++ } else { ++ netif = netif_default; /* To default network interface */ ++ } ++ if (netif == NULL) { ++ return ENXIO; ++ } ++ ++ if_idx = netif_get_index(netif); ++ if (optname == MCAST_JOIN_SOURCE_GROUP) { ++#if LWIP_IPV4 && LWIP_IGMP ++ if (IP_IS_V4(&multi_addr)) { ++ if (!lwip_socket_register_membership(s, if_idx, ip_2_ip4(&multi_addr))) { ++ /* cannot track membership (out of memory) */ ++ err = ENOMEM; ++ goto out; ++ } ++ } else ++#endif ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ if (!lwip_socket_register_mld6_membership(s, if_idx, ip_2_ip6(&multi_addr))) { ++ /* cannot track membership (out of memory) */ ++ err = ENOMEM; ++ goto out; ++ } ++#endif ++ } ++ err = mcast_join_netif(ipmc, netif, &multi_addr, &src_addr); ++ } else { ++ err = mcast_leave_netif(ipmc, netif, &multi_addr, &src_addr); ++ } ++out: ++ return err_to_errno(err); ++} ++ + /** + * setsockopt() IPV6_JOIN_GROUP / IPV6_LEAVE_GROUP command + */ +-- +2.25.1 + diff --git a/0126-add-stats_proto-in-out-to-xmit-recv.patch b/0126-add-stats_proto-in-out-to-xmit-recv.patch new file mode 100644 index 0000000..a0a08fc --- /dev/null +++ b/0126-add-stats_proto-in-out-to-xmit-recv.patch @@ -0,0 +1,419 @@ +From 050f6e547e31a6dd26837a4660ce8c53db71e272 Mon Sep 17 00:00:00 2001 +From: root +Date: Thu, 25 Apr 2024 10:57:46 +0800 +Subject: [PATCH] add stats_proto in/out to xmit/recv + +--- + src/core/ipv4/etharp.c | 25 ++++++++++++++++++++----- + src/core/ipv4/icmp.c | 22 +++++++++++++++++++++- + src/core/ipv4/ip4.c | 28 ++++++++++++++++++++++------ + src/core/tcp_in.c | 8 +++++++- + src/core/tcp_out.c | 16 +++++++++++++--- + src/core/udp.c | 21 ++++++++++++++++----- + src/include/lwip/stats.h | 6 ++++++ + 7 files changed, 105 insertions(+), 21 deletions(-) + +diff --git a/src/core/ipv4/etharp.c b/src/core/ipv4/etharp.c +index 6a9117a..ffaa442 100644 +--- a/src/core/ipv4/etharp.c ++++ b/src/core/ipv4/etharp.c +@@ -654,7 +654,9 @@ etharp_input(struct pbuf *p, struct netif *netif) + u8_t for_us, from_us; + + LWIP_ASSERT_CORE_LOCKED(); +- ++#if GAZELLE_ENABLE ++ ETHARP_STATS_INC(etharp.rx_in); ++#endif + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + + hdr = (struct etharp_hdr *)p->payload; +@@ -672,7 +674,9 @@ etharp_input(struct pbuf *p, struct netif *netif) + pbuf_free(p); + return; + } ++#if !GAZELLE_ENABLE + ETHARP_STATS_INC(etharp.recv); ++#endif + + #if LWIP_ACD + /* We have to check if a host already has configured our ip address and +@@ -746,6 +750,9 @@ etharp_input(struct pbuf *p, struct netif *netif) + break; + } + /* free ARP packet */ ++#if GAZELLE_ENABLE ++ ETHARP_STATS_INC(etharp.rx_out); ++#endif + pbuf_free(p); + } + +@@ -801,7 +808,10 @@ etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) + const struct eth_addr *dest; + struct eth_addr mcastaddr; + const ip4_addr_t *dst_addr = ipaddr; +- ++ ++#if GAZELLE_ENABLE ++ ETHARP_STATS_INC(etharp.tx_in); ++#endif + LWIP_ASSERT_CORE_LOCKED(); + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("q != NULL", q != NULL); +@@ -901,6 +911,9 @@ etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) + /* continuation for multicast/broadcast destinations */ + /* obtain source Ethernet address of the given interface */ + /* send packet directly on the link */ ++#if GAZELLE_ENABLE ++ ETHARP_STATS_INC(etharp.tx_out); ++#endif + return ethernet_output(netif, q, (struct eth_addr *)(netif->hwaddr), dest, ETHTYPE_IP); + } + +@@ -1179,13 +1192,15 @@ etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, + { + ethernet_output(netif, p, ethsrc_addr, ethdst_addr, ETHTYPE_ARP); + } +- +- ETHARP_STATS_INC(etharp.xmit); ++#if GAZELLE_ENABLE ++ ETHARP_STATS_INC(etharp.tx_out); ++#else ++ ETHARP_STATS_INC(etharp.xmit); ++#endif + /* free ARP query packet */ + pbuf_free(p); + p = NULL; + /* could not allocate pbuf for ARP request */ +- + return result; + } + +diff --git a/src/core/ipv4/icmp.c b/src/core/ipv4/icmp.c +index a3de92d..ff1ecca 100644 +--- a/src/core/ipv4/icmp.c ++++ b/src/core/ipv4/icmp.c +@@ -92,7 +92,11 @@ icmp_input(struct pbuf *p, struct netif *inp) + u16_t hlen; + const ip4_addr_t *src; + ++#if GAZELLE_ENABLE ++ ICMP_STATS_INC(icmp.rx_in); ++#else + ICMP_STATS_INC(icmp.recv); ++#endif + MIB2_STATS_INC(mib2.icmpinmsgs); + + iphdr_in = ip4_current_header(); +@@ -120,6 +124,9 @@ icmp_input(struct pbuf *p, struct netif *inp) + break; + case ICMP_ECHO: + MIB2_STATS_INC(mib2.icmpinechos); ++#if GAZELLE_ENABLE ++ ICMP_STATS_INC(icmp.tx_in); ++#endif + src = ip4_current_dest_addr(); + /* multicast destination address? */ + if (ip4_addr_ismulticast(ip4_current_dest_addr())) { +@@ -252,8 +259,11 @@ icmp_input(struct pbuf *p, struct netif *inp) + #endif + } + #endif /* CHECKSUM_GEN_IP */ +- ++#if GAZELLE_ENABLE ++ ICMP_STATS_INC(icmp.tx_out); ++#else + ICMP_STATS_INC(icmp.xmit); ++#endif + /* increase number of messages attempted to send */ + MIB2_STATS_INC(mib2.icmpoutmsgs); + /* increase number of echo replies attempted to send */ +@@ -292,6 +302,9 @@ icmp_input(struct pbuf *p, struct netif *inp) + ICMP_STATS_INC(icmp.proterr); + ICMP_STATS_INC(icmp.drop); + } ++#if GAZELLE_ENABLE ++ ICMP_STATS_INC(icmp.rx_out); ++#endif + pbuf_free(p); + return; + lenerr: +@@ -361,6 +374,9 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code) + + /* increase number of messages attempted to send */ + MIB2_STATS_INC(mib2.icmpoutmsgs); ++#if GAZELLE_ENABLE ++ ICMP_STATS_INC(icmp.tx_in); ++#endif + + /* Keep IP header + up to 8 bytes */ + response_pkt_len = IP_HLEN + ICMP_DEST_UNREACH_DATASIZE; +@@ -411,7 +427,11 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code) + icmphdr->chksum = inet_chksum(icmphdr, q->len); + } + #endif ++#if GAZELLE_ENABLE ++ ICMP_STATS_INC(icmp.tx_out); ++#else + ICMP_STATS_INC(icmp.xmit); ++#endif + ip4_output_if(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP, netif); + } + pbuf_free(q); +diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c +index 907a2f0..8865766 100644 +--- a/src/core/ipv4/ip4.c ++++ b/src/core/ipv4/ip4.c +@@ -382,7 +382,9 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) + + IP_STATS_INC(ip.fw); + MIB2_STATS_INC(mib2.ipforwdatagrams); ++#if !GAZELLE_ENABLE + IP_STATS_INC(ip.xmit); ++#endif + + #ifndef LWIP_PERF + PERF_STOP("ip4_forward"); +@@ -406,6 +408,9 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) + /* transmit pbuf on chosen interface */ + netif->output(netif, p, ip4_current_dest_addr()); + return; ++#if GAZELLE_ENABLE ++ IP_STATS_INC(ip.tx_out); ++#endif + return_noroute: + MIB2_STATS_INC(mib2.ipoutnoroutes); + } +@@ -481,8 +486,12 @@ ip4_input(struct pbuf *p, struct netif *inp) + LWIP_ASSERT_CORE_LOCKED(); + + PERF_START(PERF_LAYER_IP, PERF_POINT_IP_RECV); +- +- IP_STATS_INC(ip.recv); ++ ++#if GAZELLE_ENABLE ++ IP_STATS_INC(ip.rx_in); ++#else ++ IP_STATS_INC(ip.recv); ++#endif + MIB2_STATS_INC(mib2.ipinreceives); + + /* identify the IP header */ +@@ -815,7 +824,9 @@ ip4_input(struct pbuf *p, struct netif *inp) + ip4_addr_set_any(ip4_current_dest_addr()); + + PERF_STOP_INCREASE_COUNT("ip4_input", PERF_LAYER_IP); +- ++#if GAZELLE_ENABLE ++ IP_STATS_INC(ip.rx_out); ++#endif + return ERR_OK; + } + +@@ -908,7 +919,9 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d + #if CHECKSUM_GEN_IP_INLINE + u32_t chk_sum = 0; + #endif /* CHECKSUM_GEN_IP_INLINE */ +- ++#if GAZELLE_ENABLE ++ IP_STATS_INC(ip.tx_in); ++#endif + LWIP_ASSERT_CORE_LOCKED(); + LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); + +@@ -1045,7 +1058,9 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d + dest = &dest_addr; + } + ++#if !GAZELLE_ENABLE + IP_STATS_INC(ip.xmit); ++#endif + + LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num)); + ip4_debug_print(p); +@@ -1078,7 +1093,9 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d + } + #endif + #endif /* IP_FRAG */ +- ++#if GAZELLE_ENABLE ++ IP_STATS_INC(ip.tx_out); ++#endif + LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: call netif->output()\n")); + return netif->output(netif, p, dest); + } +@@ -1107,7 +1124,6 @@ ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, + struct netif *netif; + + LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); +- + if ((netif = ip4_route_src(src, dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); +diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c +index 2922721..6c960a6 100644 +--- a/src/core/tcp_in.c ++++ b/src/core/tcp_in.c +@@ -179,8 +179,11 @@ tcp_input(struct pbuf *p, struct netif *inp) + #ifndef LWIP_PERF + PERF_START; + #endif +- ++#if GAZELLE_ENABLE ++ TCP_STATS_INC(tcp.rx_in); ++#else + TCP_STATS_INC(tcp.recv); ++#endif + MIB2_STATS_INC(mib2.tcpinsegs); + + tcphdr = (struct tcp_hdr *)p->payload; +@@ -675,6 +678,9 @@ tcp_input(struct pbuf *p, struct netif *inp) + #endif /* TCP_INPUT_DEBUG */ + } + } ++#if GAZELLE_ENABLE ++ TCP_STATS_INC(tcp.rx_out); ++#endif + /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()). + Below this line, 'pcb' may not be dereferenced! */ + aborted: +diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c +index 1632a66..8a9016b 100644 +--- a/src/core/tcp_out.c ++++ b/src/core/tcp_out.c +@@ -1467,7 +1467,9 @@ tcp_output(struct tcp_pcb *pcb) + #endif /* TCP_CWND_DEBUG */ + + LWIP_ASSERT_CORE_LOCKED(); +- ++#if GAZELLE_ENABLE ++ TCP_STATS_INC(tcp.tx_in); ++#endif + LWIP_ASSERT("tcp_output: invalid pcb", pcb != NULL); + /* pcb->state LISTEN not allowed here */ + LWIP_ASSERT("don't call tcp_output for listen-pcbs", +@@ -2019,8 +2021,9 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif + #endif /* CHECKSUM_GEN_TCP_HW */ + } + #endif /* CHECKSUM_GEN_TCP */ ++#if !GAZELLE_ENABLE + TCP_STATS_INC(tcp.xmit); +- ++#endif + PERF_PAUSE_RETURN_POINT(PERF_LAYER_TCP, tmpPoint); + PERF_START(PERF_LAYER_IP, PERF_POINT_IP_SEND); + +@@ -2039,7 +2042,9 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif + seg->chksum_swapped = 1; + } + #endif +- ++#if GAZELLE_ENABLE ++ TCP_STATS_INC(tcp.tx_out); ++#endif + PERF_STOP_INCREASE_COUNT("ip_out", PERF_LAYER_IP); + PERF_RESUME(PERF_LAYER_TCP, tmpPoint); + +@@ -2430,7 +2435,12 @@ tcp_output_control_segment_netif(const struct tcp_pcb *pcb, struct pbuf *p, + ttl = TCP_TTL; + tos = 0; + } ++#if GAZELLE_ENABLE ++ TCP_STATS_INC(tcp.tx_out); ++#else + TCP_STATS_INC(tcp.xmit); ++#endif ++ + err = ip_output_if(p, src, dst, ttl, tos, IP_PROTO_TCP, netif); + NETIF_RESET_HINTS(netif); + +diff --git a/src/core/udp.c b/src/core/udp.c +index 4a47e99..2c946c7 100644 +--- a/src/core/udp.c ++++ b/src/core/udp.c +@@ -263,7 +263,9 @@ udp_input(struct pbuf *p, struct netif *inp) + LWIP_UNUSED_ARG(inp); + + LWIP_ASSERT_CORE_LOCKED(); +- ++#if GAZELLE_ENABLE ++ UDP_STATS_INC(udp.rx_in); ++#endif + LWIP_ASSERT("udp_input: invalid pbuf", p != NULL); + LWIP_ASSERT("udp_input: invalid netif", inp != NULL); + +@@ -273,7 +275,9 @@ udp_input(struct pbuf *p, struct netif *inp) + //PERF_START; + #endif + ++#if !GAZELLE_ENABLE + UDP_STATS_INC(udp.recv); ++#endif + + /* Check minimum length (UDP header) */ + if (p->len < UDP_HLEN) { +@@ -518,6 +522,9 @@ udp_input(struct pbuf *p, struct netif *inp) + } else { + pbuf_free(p); + } ++#if GAZELLE_ENABLE ++ UDP_STATS_INC(udp.rx_out); ++#endif + end: + #if LWIP_RECORD_PERF + PERF_STOP_INCREASE_COUNT("udp_input", PERF_LAYER_UDP); +@@ -589,7 +596,6 @@ udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, + { + LWIP_ERROR("udp_send_chksum: invalid pcb", pcb != NULL, return ERR_ARG); + LWIP_ERROR("udp_send_chksum: invalid pbuf", p != NULL, return ERR_ARG); +- + if (IP_IS_ANY_TYPE_VAL(pcb->remote_ip)) { + return ERR_VAL; + } +@@ -839,9 +845,11 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d + struct pbuf *q; /* q will be sent down the stack */ + u8_t ip_proto; + u8_t ttl; +- ++ + LWIP_ASSERT_CORE_LOCKED(); +- ++#if GAZELLE_ENABLE ++ UDP_STATS_INC(udp.tx_in); ++#endif + LWIP_ERROR("udp_sendto_if_src: invalid pcb", pcb != NULL, return ERR_ARG); + LWIP_ERROR("udp_sendto_if_src: invalid pbuf", p != NULL, return ERR_ARG); + LWIP_ERROR("udp_sendto_if_src: invalid dst_ip", dst_ip != NULL, return ERR_ARG); +@@ -1057,8 +1065,11 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d + q = NULL; + /* p is still referenced by the caller, and will live on */ + } +- ++#if GAZELLE_ENABLE ++ UDP_STATS_INC(udp.tx_out); ++#else + UDP_STATS_INC(udp.xmit); ++#endif + return err; + } + +diff --git a/src/include/lwip/stats.h b/src/include/lwip/stats.h +index 08c34e9..f99f6e5 100644 +--- a/src/include/lwip/stats.h ++++ b/src/include/lwip/stats.h +@@ -64,6 +64,12 @@ extern "C" { + struct stats_proto { + STAT_COUNTER xmit; /* Transmitted packets. */ + STAT_COUNTER recv; /* Received packets. */ ++#if GAZELLE_ENABLE ++ STAT_COUNTER tx_in; /* Transmitted packets. */ ++ STAT_COUNTER tx_out; /* Transmitted out packets. */ ++ STAT_COUNTER rx_in; /* Received in packets. */ ++ STAT_COUNTER rx_out; /* Received out packets. */ ++#endif + STAT_COUNTER fw; /* Forwarded packets. */ + STAT_COUNTER drop; /* Dropped packets. */ + STAT_COUNTER chkerr; /* Checksum error. */ +-- +2.27.0 + diff --git a/0127-add-MCAST_BLOCK_SOURCE-to-setsockopt-for-mldv2.patch b/0127-add-MCAST_BLOCK_SOURCE-to-setsockopt-for-mldv2.patch new file mode 100644 index 0000000..3357b3a --- /dev/null +++ b/0127-add-MCAST_BLOCK_SOURCE-to-setsockopt-for-mldv2.patch @@ -0,0 +1,104 @@ +From a4a51288e841fc066cc6ab079c63eb1f113fa2ab Mon Sep 17 00:00:00 2001 +From: wanfeng +Date: Tue, 16 Apr 2024 15:51:09 +0800 +Subject: [PATCH] add MCAST_BLOCK_SOURCE to setsockopt for mldv2 + +--- + src/api/sockets.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 74 insertions(+) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index 50fa335..6a3ec91 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -3993,6 +3993,29 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ + if (NETCONNTYPE_GROUPV6(netconn_type(sock->conn)) == NETCONN_RAW_IPV6) { + err = mcast_sock_join_leave_source_group(s, &sock->conn->pcb.raw->ipmc, optname, (const struct group_source_req *)optval); + } else ++#endif /* LWIP_RAW */ ++ { ++ done_socket(sock); ++ return ENOPROTOOPT; ++ } ++ break; ++ case MCAST_BLOCK_SOURCE: ++ case MCAST_UNBLOCK_SOURCE: ++ LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, struct group_source_req); ++ if ((((const struct group_source_req *)optval)->gsr_group.ss_family != AF_INET6) || ++ (((const struct group_source_req *)optval)->gsr_source.ss_family != AF_INET6)) { ++ done_socket(sock); ++ return EINVAL; ++ } ++#if LWIP_UDP ++ if (NETCONNTYPE_GROUPV6(netconn_type(sock->conn)) == NETCONN_UDP_IPV6) { ++ err = mcast_sock_block_unblock_source_group(&sock->conn->pcb.udp->ipmc, optname, (const struct group_source_req *)optval); ++ } else ++#endif /* LWIP_UDP */ ++#if LWIP_RAW ++ if (NETCONNTYPE_GROUPV6(netconn_type(sock->conn)) == NETCONN_RAW_IPV6) { ++ err = mcast_sock_block_unblock_source_group(&sock->conn->pcb.raw->ipmc, optname, (const struct group_source_req *)optval); ++ } else + #endif /* LWIP_RAW */ + { + done_socket(sock); +@@ -4963,6 +4986,57 @@ out: + return err_to_errno(err); + } + ++/** ++ * setsockopt() MCAST_BLOCK_SOURCE / MCAST_UNBLOCK_SOURCE command ++ */ ++int ++mcast_sock_block_unblock_source_group(struct ip_mc *ipmc, int optname, const struct group_source_req *gsr) ++{ ++ struct netif *netif; ++ ip_addr_t multi_addr; ++ ip_addr_t blk_addr; ++ err_t err; ++ ++ if (gsr->gsr_group.ss_family == AF_INET) { ++ inet_addr_to_ip4addr(ip_2_ip4(&multi_addr), &(((struct sockaddr_in *)&(gsr->gsr_group))->sin_addr)); ++ inet_addr_to_ip4addr(ip_2_ip4(&blk_addr), &(((struct sockaddr_in *)&(gsr->gsr_source))->sin_addr)); ++ IP_SET_TYPE_VAL(multi_addr, IPADDR_TYPE_V4); ++ IP_SET_TYPE_VAL(blk_addr, IPADDR_TYPE_V4); ++ if (!ip4_addr_ismulticast(ip_2_ip4(&multi_addr)) || ip4_addr_isany(ip_2_ip4(&blk_addr))) { ++ return EADDRNOTAVAIL; ++ } ++ ++ } else if (gsr->gsr_group.ss_family == AF_INET6) { ++ inet6_addr_to_ip6addr(ip_2_ip6(&multi_addr), &(((struct sockaddr_in6 *)&(gsr->gsr_group))->sin6_addr)); ++ inet6_addr_to_ip6addr(ip_2_ip6(&blk_addr), &(((struct sockaddr_in6 *)&(gsr->gsr_source))->sin6_addr)); ++ IP_SET_TYPE_VAL(multi_addr, IPADDR_TYPE_V6); ++ IP_SET_TYPE_VAL(blk_addr, IPADDR_TYPE_V6); ++ if (!ip6_addr_ismulticast(ip_2_ip6(&multi_addr)) || ip6_addr_isany(ip_2_ip6(&blk_addr))) { ++ return EADDRNOTAVAIL; ++ } ++ ++ } else { ++ return EADDRNOTAVAIL; ++ } ++ ++ if (gsr->gsr_interface) { ++ netif = netif_get_by_index((u8_t)gsr->gsr_interface); ++ } else { ++ netif = netif_default; /* To default network interface */ ++ } ++ if (netif == NULL) { ++ return ENXIO; ++ } ++ ++ if (optname == MCAST_BLOCK_SOURCE) { ++ err = mcast_block_netif(ipmc, netif, &multi_addr, &blk_addr); ++ } else { ++ err = mcast_unblock_netif(ipmc, netif, &multi_addr, &blk_addr); ++ } ++ ++ return err_to_errno(err); ++} ++ + /** + * setsockopt() IPV6_JOIN_GROUP / IPV6_LEAVE_GROUP command + */ +-- +2.25.1 + diff --git a/0128-add-MCAST_JOIN_SOURCE_GROUP-to-setsockopt-for-igmpv3.patch b/0128-add-MCAST_JOIN_SOURCE_GROUP-to-setsockopt-for-igmpv3.patch new file mode 100644 index 0000000..f5cd2ea --- /dev/null +++ b/0128-add-MCAST_JOIN_SOURCE_GROUP-to-setsockopt-for-igmpv3.patch @@ -0,0 +1,33 @@ +diff -Nur lwip-2.2.0old/src/api/sockets.c lwip-2.2.0/src/api/sockets.c +--- lwip-2.2.0old/src/api/sockets.c 2024-04-29 10:39:04.721200645 +0800 ++++ lwip-2.2.0/src/api/sockets.c 2024-04-29 11:21:09.036645032 +0800 +@@ -3859,6 +3859,29 @@ + return ENOPROTOOPT; + } + break; ++ case MCAST_JOIN_SOURCE_GROUP: ++ case MCAST_LEAVE_SOURCE_GROUP: ++ LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, struct group_source_req); ++ if ((((const struct group_source_req *)optval)->gsr_group.ss_family != AF_INET) || ++ (((const struct group_source_req *)optval)->gsr_source.ss_family != AF_INET)) { ++ done_socket(sock); ++ return EINVAL; ++ } ++#if LWIP_UDP ++ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_UDP) { ++ err = mcast_sock_join_leave_source_group(s,&sock->conn->pcb.udp->ipmc, optname, (const struct group_source_req *)optval); ++ } else ++#endif /* LWIP_UDP */ ++#if LWIP_RAW ++ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_RAW) { ++ err = mcast_sock_join_leave_source_group(s,&sock->conn->pcb.raw->ipmc, optname, (const struct group_source_req *)optval); ++ } else ++#endif /* LWIP_RAW */ ++ { ++ done_socket(sock); ++ return ENOPROTOOPT; ++ } ++ break; + #endif /* LWIP_IGMP */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", diff --git a/0129-memset-gazelle_quintuple-in-vdev_reg_done.patch b/0129-memset-gazelle_quintuple-in-vdev_reg_done.patch new file mode 100644 index 0000000..7c3f2d1 --- /dev/null +++ b/0129-memset-gazelle_quintuple-in-vdev_reg_done.patch @@ -0,0 +1,25 @@ +From beadb61ae1e366ea1f7a2e53d96251ea6f40490e Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Tue, 30 Apr 2024 10:09:18 +0800 +Subject: [PATCH] memset gazelle_quintuple in vdev_reg_done + +--- + src/include/lwip/priv/tcp_priv.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h +index 8d7b9df..7ef00fa 100644 +--- a/src/include/lwip/priv/tcp_priv.h ++++ b/src/include/lwip/priv/tcp_priv.h +@@ -346,7 +346,7 @@ static inline int vdev_reg_done(enum reg_ring_type reg_type, const struct tcp_pc + { + LWIP_ASSERT("Invalid parameter", pcb != NULL); + +- struct gazelle_quintuple qtuple; ++ struct gazelle_quintuple qtuple = {0}; + + qtuple.protocol = IP_IS_V4_VAL(pcb->local_ip) ? GZ_ADDR_TYPE_V4 : GZ_ADDR_TYPE_V6; + qtuple.src_ip = *((gz_addr_t *)&pcb->local_ip); +-- +2.33.0 + diff --git a/0130-add-MCAST_JOIN_GROUP-to-setsockopt-for-igmpv3.patch b/0130-add-MCAST_JOIN_GROUP-to-setsockopt-for-igmpv3.patch new file mode 100644 index 0000000..39925c7 --- /dev/null +++ b/0130-add-MCAST_JOIN_GROUP-to-setsockopt-for-igmpv3.patch @@ -0,0 +1,33 @@ +diff -Nur lwip-2.2.0old/src/api/sockets.c lwip-2.2.0/src/api/sockets.c +--- lwip-2.2.0old/src/api/sockets.c 2024-04-30 10:27:19.406967694 +0800 ++++ lwip-2.2.0/src/api/sockets.c 2024-04-30 10:37:41.203874969 +0800 +@@ -3859,6 +3859,29 @@ + return ENOPROTOOPT; + } + break; ++ case MCAST_JOIN_GROUP: ++ case MCAST_LEAVE_GROUP: { ++ LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, struct group_req); ++ if (((const struct group_req *)optval)->gr_group.ss_family != AF_INET) { ++ done_socket(sock); ++ return EINVAL; ++ } ++#if LWIP_UDP ++ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_UDP) { ++ err = mcast_sock_join_leave_group(s,&sock->conn->pcb.udp->ipmc, optname, (const struct group_req *)optval); ++ } else ++#endif /* LWIP_UDP */ ++#if LWIP_RAW ++ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_RAW) { ++ err = mcast_sock_join_leave_group(s,&sock->conn->pcb.raw->ipmc, optname, (const struct group_req *)optval); ++ } else ++#endif /* LWIP_RAW */ ++ { ++ done_socket(sock); ++ return ENOPROTOOPT; ++ } ++ } ++ break; + case MCAST_JOIN_SOURCE_GROUP: + case MCAST_LEAVE_SOURCE_GROUP: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, struct group_source_req); diff --git a/0131-add-MCAST_BLOCK_SOURCE-to-setsockopt-for-igmpv3.patch b/0131-add-MCAST_BLOCK_SOURCE-to-setsockopt-for-igmpv3.patch new file mode 100644 index 0000000..1ebf734 --- /dev/null +++ b/0131-add-MCAST_BLOCK_SOURCE-to-setsockopt-for-igmpv3.patch @@ -0,0 +1,33 @@ +diff -Nur lwip-2.2.0old/src/api/sockets.c lwip-2.2.0/src/api/sockets.c +--- lwip-2.2.0old/src/api/sockets.c 2024-05-07 11:16:33.896085084 +0800 ++++ lwip-2.2.0/src/api/sockets.c 2024-05-07 11:27:00.444968722 +0800 +@@ -3905,6 +3905,29 @@ + return ENOPROTOOPT; + } + break; ++ case MCAST_BLOCK_SOURCE: ++ case MCAST_UNBLOCK_SOURCE: ++ LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, struct group_source_req); ++ if ((((const struct group_source_req *)optval)->gsr_group.ss_family != AF_INET) || ++ (((const struct group_source_req *)optval)->gsr_source.ss_family != AF_INET)) { ++ done_socket(sock); ++ return EINVAL; ++ } ++#if LWIP_UDP ++ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_UDP) { ++ err = mcast_sock_block_unblock_source_group(&sock->conn->pcb.udp->ipmc, optname, (const struct group_source_req *)optval); ++ } else ++#endif /* LWIP_UDP */ ++#if LWIP_RAW ++ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_RAW) { ++ err = mcast_sock_block_unblock_source_group(&sock->conn->pcb.raw->ipmc, optname, (const struct group_source_req *)optval); ++ } else ++#endif /* LWIP_RAW */ ++ { ++ done_socket(sock); ++ return ENOPROTOOPT; ++ } ++ break; + #endif /* LWIP_IGMP */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", diff --git a/0132-mod-udp-loop-mem-leak.patch b/0132-mod-udp-loop-mem-leak.patch new file mode 100644 index 0000000..7f930dc --- /dev/null +++ b/0132-mod-udp-loop-mem-leak.patch @@ -0,0 +1,79 @@ +From 817a3b938db89efa8ef63d610b43cb10321da446 Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Tue, 7 May 2024 17:49:32 +0800 +Subject: [PATCH] mod udp loop mem leak + +--- + src/core/netif.c | 21 +++++++++++++++------ + src/core/pbuf.c | 20 +++++++++++++++++--- + 2 files changed, 32 insertions(+), 9 deletions(-) + +diff --git a/src/core/netif.c b/src/core/netif.c +index 2fc8945..e6cdebe 100644 +--- a/src/core/netif.c ++++ b/src/core/netif.c +@@ -1182,13 +1182,22 @@ udp_netif_loop_output(struct netif *netif, struct pbuf *p) + LWIP_ASSERT("netif_loop_output: invalid pbuf", p != NULL); + + /* Allocate a new pbuf */ +- r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); +- if (r == NULL) { +- LINK_STATS_INC(link.memerr); +- LINK_STATS_INC(link.drop); +- MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards); +- return ERR_MEM; ++ u16_t p_clen = pbuf_clen(p); ++ struct pbuf *temp[p_clen]; ++ for (int i = 0; i < p_clen; i++) { ++ temp[i] = pbuf_alloc(PBUF_LINK, p->len, PBUF_RAM); ++ if (temp[i] == NULL) { ++ LINK_STATS_INC(link.memerr); ++ LINK_STATS_INC(link.drop); ++ MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards); ++ pbuf_free(temp[0]); ++ return ERR_MEM; ++ } ++ if (i > 0) { ++ pbuf_cat(temp[0], temp[i]); ++ } + } ++ r = temp[0]; + #if LWIP_LOOPBACK_MAX_PBUFS + clen = pbuf_clen(r); + /* check for overflow or too many pbuf on queue */ +diff --git a/src/core/pbuf.c b/src/core/pbuf.c +index b0a63b4..914d1f4 100644 +--- a/src/core/pbuf.c ++++ b/src/core/pbuf.c +@@ -1373,11 +1373,25 @@ pbuf_clone(pbuf_layer layer, pbuf_type type, struct pbuf *p) + { + struct pbuf *q; + err_t err; +- q = pbuf_alloc(layer, p->tot_len, type); +- if (q == NULL) { +- return NULL; ++ u16_t p_clen = pbuf_clen(p); ++ struct pbuf *temp[p_clen]; ++ for (int i = 0; i < p_clen; i++) { ++ temp[i] = pbuf_alloc(PBUF_LINK, p->len, PBUF_RAM); ++ if (temp[i] == NULL) { ++ pbuf_free(temp[0]); ++ return NULL; ++ } ++ if (i > 0) { ++ pbuf_cat(temp[0], temp[i]); ++ } + } ++ q = temp[0]; ++ + err = pbuf_copy(q, p); ++ if (err != ERR_OK) { ++ pbuf_free(q); ++ return NULL; ++ } + LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */ + LWIP_ASSERT("pbuf_copy failed", err == ERR_OK); + return q; +-- +2.33.0 + diff --git a/0133-allow-membership-to-register-multiple-times.patch b/0133-allow-membership-to-register-multiple-times.patch new file mode 100644 index 0000000..2249b9a --- /dev/null +++ b/0133-allow-membership-to-register-multiple-times.patch @@ -0,0 +1,34 @@ +From 3b23b3a69d71a862dfe7fca1b53b673dc868ffa5 Mon Sep 17 00:00:00 2001 +From: wanfeng +Date: Fri, 10 May 2024 15:11:12 +0800 +Subject: [PATCH] allow membership to register multiple times + +--- + src/api/sockets.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index 04df15a..5a72b62 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -4501,7 +4501,7 @@ lwip_socket_register_membership(int s, unsigned int if_idx, const ip4_addr_t *mu + #else + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + #endif +- if (socket_ipv4_multicast_memberships[i].sock == NULL) { ++ if (socket_ipv4_multicast_memberships[i].sock == NULL || (socket_ipv4_multicast_memberships[i].sock == sock)) { + socket_ipv4_multicast_memberships[i].sock = sock; + socket_ipv4_multicast_memberships[i].if_idx = if_idx; + ip4_addr_copy(socket_ipv4_multicast_memberships[i].multi_addr, *multi_addr); +@@ -4617,7 +4617,7 @@ lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_ + #else + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + #endif +- if (socket_ipv6_multicast_memberships[i].sock == NULL) { ++ if (socket_ipv6_multicast_memberships[i].sock == NULL || (socket_ipv6_multicast_memberships[i].sock == sock)) { + socket_ipv6_multicast_memberships[i].sock = sock; + socket_ipv6_multicast_memberships[i].if_idx = (u8_t)if_idx; + ip6_addr_copy(socket_ipv6_multicast_memberships[i].multi_addr, *multi_addr); +-- +2.25.1 + diff --git a/0134-mod-checksum-of-ip_hdr-and-udp_hdr.patch b/0134-mod-checksum-of-ip_hdr-and-udp_hdr.patch new file mode 100644 index 0000000..41456d7 --- /dev/null +++ b/0134-mod-checksum-of-ip_hdr-and-udp_hdr.patch @@ -0,0 +1,53 @@ +From c465aa8bce75770ed296862657118d0ceaf4087b Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Thu, 9 May 2024 20:06:50 +0800 +Subject: [PATCH] mod checksum of ip_hdr and udp_hdr + +--- + src/core/ipv4/ip4.c | 2 +- + src/core/ipv4/ip4_frag.c | 1 + + src/core/udp.c | 3 ++- + 3 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c +index 8865766..0bbeefc 100644 +--- a/src/core/ipv4/ip4.c ++++ b/src/core/ipv4/ip4.c +@@ -1084,7 +1084,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d + #if IP_FRAG + /* don't fragment if interface has mtu set to 0 [loopif] */ + #if GAZELLE_ENABLE +- if (!(netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_TCP_TSO)) { ++ if ((!(netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_TCP_TSO)) || !(IPH_PROTO(iphdr) == IP_PROTO_TCP)) { + #endif + if (netif->mtu && (p->tot_len > netif->mtu)) { + return ip4_frag(p, netif, dest); +diff --git a/src/core/ipv4/ip4_frag.c b/src/core/ipv4/ip4_frag.c +index aa50856..2ba473b 100644 +--- a/src/core/ipv4/ip4_frag.c ++++ b/src/core/ipv4/ip4_frag.c +@@ -892,6 +892,7 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest) + #if CHECKSUM_GEN_IP_HW + if (netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) { + iph_cksum_set(p, IP_HLEN, 1); ++ iph_cksum_set(rambuf, IP_HLEN, 1); + } else { + iph_cksum_set(p, IP_HLEN, 0); + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); +diff --git a/src/core/udp.c b/src/core/udp.c +index 2c946c7..1fae8b6 100644 +--- a/src/core/udp.c ++++ b/src/core/udp.c +@@ -1011,7 +1011,8 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d + #endif /* LWIP_CHECKSUM_ON_COPY */ + { + #if CHECKSUM_GEN_UDP_HW +- if (netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) { ++ if ( (netif_get_txol_flags(netif) & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) && ++ (netif->mtu) && (p->tot_len <= netif->mtu)) { + udph_cksum_set(q, UDP_HLEN); + udpchksum = 0; + } else { +-- +2.33.0 + diff --git a/0135-change-STAT_COUNTER-from-u16-to-u64.patch b/0135-change-STAT_COUNTER-from-u16-to-u64.patch new file mode 100644 index 0000000..8b4143e --- /dev/null +++ b/0135-change-STAT_COUNTER-from-u16-to-u64.patch @@ -0,0 +1,28 @@ +From 2d03a11cfbbe8885339fda776f45ad3d26829d9f Mon Sep 17 00:00:00 2001 +From: ningjin +Date: Mon, 20 May 2024 17:33:12 +0800 +Subject: [PATCH] change STAT_COUNTER from u16 to u64 + +--- + src/include/lwip/stats.h | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/include/lwip/stats.h b/src/include/lwip/stats.h +index f99f6e5..6798f48 100644 +--- a/src/include/lwip/stats.h ++++ b/src/include/lwip/stats.h +@@ -52,7 +52,10 @@ extern "C" { + #define LWIP_STATS_LARGE 0 + #endif + +-#if LWIP_STATS_LARGE ++#if GAZELLE_ENABLE ++#define STAT_COUNTER u64_t ++#define STAT_COUNTER_F U64_F ++#elif LWIP_STATS_LARGE + #define STAT_COUNTER u32_t + #define STAT_COUNTER_F U32_F + #else +-- +2.27.0 + diff --git a/0136-fix-vlan-filter-bug.patch b/0136-fix-vlan-filter-bug.patch new file mode 100644 index 0000000..6904930 --- /dev/null +++ b/0136-fix-vlan-filter-bug.patch @@ -0,0 +1,25 @@ +diff --git a/src/netif/ethernet.c b/src/netif/ethernet.c +index d0d68b3..5ba6d95 100644 +--- a/src/netif/ethernet.c ++++ b/src/netif/ethernet.c +@@ -123,7 +123,9 @@ ethernet_input(struct pbuf *p, struct netif *netif) + goto free_and_return; + } + #if GAZELLE_ENABLE +- if (netif->vlan_enable && !(netif->txol_flags & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) && VLAN_ID(vlan) != netif->vlan_tci) { ++ /* 1.if vlan mode is not enable, ignore VLAN packets. ++ 2.if vlan mode is enable, ignore packets not for our VLAN */ ++ if (netif->vlan_enable == false || (netif->vlan_enable && VLAN_ID(vlan) != netif->vlan_tci)) { + goto free_and_return; + } + #endif +@@ -141,6 +143,9 @@ ethernet_input(struct pbuf *p, struct netif *netif) + } + #endif /* defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */ + type = vlan->tpid; ++ } else if (netif->vlan_enable && !(netif->txol_flags & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)) { ++ /* if vlan mode is enable but vlan strip offload is off, ignore packets without vlan info. */ ++ goto free_and_return; + } + #endif /* ETHARP_SUPPORT_VLAN */ + diff --git a/backport-Add-outgoing-VLAN-PCP-support.patch b/backport-Add-outgoing-VLAN-PCP-support.patch deleted file mode 100644 index 7f89e9c..0000000 --- a/backport-Add-outgoing-VLAN-PCP-support.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 95aba99f41333ad430496eab2596bc8b489ae731 Mon Sep 17 00:00:00 2001 -From: Dirk Ziegelmeier -Date: Fri, 19 Oct 2018 22:30:17 +0200 -Subject: [PATCH] Implement task #11620: Add outgoing VLAN PCP support for - Ethernet level QoS - -Apply rebased patch from Timmy Brolin ---- - src/core/tcp.c | 29 ++++++++++++++++------------- - src/core/tcp_in.c | 3 +++ - src/include/lwip/netif.h | 22 ++++++++++++++-------- - src/include/lwip/opt.h | 34 +++++++++++++++++++++++----------- - src/netif/ethernet.c | 12 ++++++++++-- - 5 files changed, 66 insertions(+), 34 deletions(-) - -diff --git a/src/core/tcp.c b/src/core/tcp.c -index ce03c8161..1f91d24ba 100644 ---- a/src/core/tcp.c -+++ b/src/core/tcp.c -@@ -892,6 +892,9 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) - lpcb->ttl = pcb->ttl; - lpcb->tos = pcb->tos; - -+#if LWIP_VLAN_PCP -+ lpcb->netif_hints.tci = pcb->netif_hints.tci; -+#endif /* LWIP_VLAN_PCP */ - #if GAZELLE_TCP_REUSE_IPPORT - lpcb->connect_num = 0; - lpcb->next_same_port_pcb = NULL; -index 428a6f48d..d1fe067a4 100644 ---- a/src/core/tcp_in.c -+++ b/src/core/tcp_in.c -@@ -690,6 +690,9 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) - #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG - npcb->listener = pcb; - #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ -+#if LWIP_VLAN_PCP -+ npcb->netif_hints.tci = pcb->netif_hints.tci; -+#endif /* LWIP_VLAN_PCP */ - /* inherit socket options */ - npcb->so_options = pcb->so_options & SOF_INHERITED; - npcb->netif_idx = pcb->netif_idx; -diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h -index 9e2007a64..013a69b5a 100644 ---- a/src/include/lwip/netif.h -+++ b/src/include/lwip/netif.h -@@ -248,14 +248,20 @@ typedef u8_t netif_addr_idx_t; - #define NETIF_ADDR_IDX_MAX 0x7F - #endif - -+#if LWIP_NETIF_HWADDRHINT || LWIP_VLAN_PCP -+ #define LWIP_NETIF_USE_HINTS 1 -+ struct netif_hint { - #if LWIP_NETIF_HWADDRHINT --#define LWIP_NETIF_USE_HINTS 1 --struct netif_hint { -- netif_addr_idx_t addr_hint; --}; --#else /* LWIP_NETIF_HWADDRHINT */ --#define LWIP_NETIF_USE_HINTS 0 --#endif /* LWIP_NETIF_HWADDRHINT */ -+ u8_t addr_hint; -+#endif -+#if LWIP_VLAN_PCP -+ /** VLAN hader is set if this is >= 0 (but must be <= 0xFFFF) */ -+ s32_t tci; -+#endif -+ }; -+#else /* LWIP_NETIF_HWADDRHINT || LWIP_VLAN_PCP */ -+ #define LWIP_NETIF_USE_HINTS 0 -+#endif /* LWIP_NETIF_HWADDRHINT || LWIP_VLAN_PCP*/ - - /** Generic data structure used for all lwIP network interfaces. - * The following fields should be filled in by the initialization - #if LWIP_IPV6_AUTOCONFIG -diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h -index 90fce4f05..fb4b10c8b 100644 ---- a/src/include/lwip/opt.h -+++ b/src/include/lwip/opt.h -@@ -677,6 +677,18 @@ - #define ETHARP_SUPPORT_VLAN 0 - #endif - -+/** -+ * LWIP_VLAN_PCP==1: Enable outgoing VLAN taggning of frames on a per-PCB basis -+ * for QoS purposes. With this feature enabled, each PCB has a new variable: "tci". -+ * (Tag Control Identifier). The TCI contains three fields: VID, CFI and PCP. -+ * VID is the VLAN ID, which should be set to zero. -+ * The "CFI" bit is used to enable or disable VLAN tags for the PCB. -+ * PCP (Priority Code Point) is a 3 bit field used for Ethernet level QoS. -+ */ -+#ifndef LWIP_VLAN_PCP -+#define LWIP_VLAN_PCP 0 -+#endif -+ - /** LWIP_ETHERNET==1: enable ethernet support even though ARP might be disabled - */ - #if !defined LWIP_ETHERNET || defined __DOXYGEN__ -@@ -1548,13 +1560,13 @@ - * link level header. The default is 14, the standard value for - * Ethernet. - */ --#if !defined PBUF_LINK_HLEN || defined __DOXYGEN__ --#if defined LWIP_HOOK_VLAN_SET && !defined __DOXYGEN__ --#define PBUF_LINK_HLEN (18 + ETH_PAD_SIZE) --#else /* LWIP_HOOK_VLAN_SET */ --#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) --#endif /* LWIP_HOOK_VLAN_SET */ --#endif -+ #if !defined PBUF_LINK_HLEN || defined __DOXYGEN__ -+#if (defined LWIP_HOOK_VLAN_SET || LWIP_VLAN_PCP) && !defined __DOXYGEN__ -+ #define PBUF_LINK_HLEN (18 + ETH_PAD_SIZE) -+#else /* LWIP_HOOK_VLAN_SET || LWIP_VLAN_PCP */ -+ #define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) -+#endif /* LWIP_HOOK_VLAN_SET || LWIP_VLAN_PCP */ -+ #endif - - /** - * PBUF_LINK_ENCAPSULATION_HLEN: the number of bytes that should be allocated -diff --git a/src/netif/ethernet.c b/src/netif/ethernet.c -index dd171e280..9e367f8cc 100644 ---- a/src/netif/ethernet.c -+++ b/src/netif/ethernet.c -@@ -273,8 +273,16 @@ ethernet_output(struct netif * netif, struct pbuf * p, - struct eth_hdr *ethhdr; - u16_t eth_type_be = lwip_htons(eth_type); - --#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) -- s32_t vlan_prio_vid = LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type); -+#if ETHARP_SUPPORT_VLAN -+ s32_t vlan_prio_vid; -+#ifdef LWIP_HOOK_VLAN_SET -+ vlan_prio_vid = LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type); -+#elif LWIP_VLAN_PCP -+ vlan_prio_vid = -1; -+ if (netif->hints && (netif->hints->tci >= 0)) { -+ vlan_prio_vid = (u16_t)netif->hints->tci; -+ } -+#endif - if (vlan_prio_vid >= 0) { - struct eth_vlan_hdr *vlanhdr; - - diff --git a/backport-fix-compiling-ETHARP_SUPPORT_VLAN.patch b/backport-fix-compiling-ETHARP_SUPPORT_VLAN.patch deleted file mode 100644 index d601427..0000000 --- a/backport-fix-compiling-ETHARP_SUPPORT_VLAN.patch +++ /dev/null @@ -1,33 +0,0 @@ -From f72227aadcc1d0d8c46a8b4fe62ba3d03ffa42c3 Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Wed, 7 Nov 2018 10:49:06 +0100 -Subject: [PATCH] fix compiling ETHARP_SUPPORT_VLAN without LWIP_HOOK_VLAN_SET - and LWIP_VLAN_PCP - ---- - src/netif/ethernet.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/netif/ethernet.c b/src/netif/ethernet.c -index 9e367f8cc..6db434b46 100644 ---- a/src/netif/ethernet.c -+++ b/src/netif/ethernet.c -@@ -273,7 +273,7 @@ ethernet_output(struct netif * netif, struct pbuf * p, - struct eth_hdr *ethhdr; - u16_t eth_type_be = lwip_htons(eth_type); - --#if ETHARP_SUPPORT_VLAN -+#if ETHARP_SUPPORT_VLAN && (defined(LWIP_HOOK_VLAN_SET) || LWIP_VLAN_PCP) - s32_t vlan_prio_vid; - #ifdef LWIP_HOOK_VLAN_SET - vlan_prio_vid = LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type); -@@ -297,7 +297,7 @@ ethernet_output(struct netif * netif, struct pbuf * p, - - eth_type_be = PP_HTONS(ETHTYPE_VLAN); - } else --#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ -+#endif /* ETHARP_SUPPORT_VLAN && (defined(LWIP_HOOK_VLAN_SET) || LWIP_VLAN_PCP) */ - { - if (pbuf_add_header(p, SIZEOF_ETH_HDR) != 0) { - goto pbuf_header_failed; - diff --git a/backport-tcp-fix-sequence-number-comparison.patch b/backport-tcp-fix-sequence-number-comparison.patch deleted file mode 100644 index 5c0f960..0000000 --- a/backport-tcp-fix-sequence-number-comparison.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 003d34eebd223c16a3dbf6a970bb6e23cb7d1a24 Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Fri, 27 Mar 2020 22:59:05 +0100 -Subject: [PATCH] tcp: fix sequence number comparison -This fixes both undefined behavior (see bug #51447) as well as a possible bug -where sequence numbers in 31 bit distance may come through. -Conflict: NA -Reference: https://git.savannah.gnu.org/cgit/lwip.git/commit/?id=003d34eebd223c16a3dbf6a970bb6e23cb7d1a24 ---- - src/include/lwip/priv/tcp_priv.h | 11 ++++------- - 1 file changed, 4 insertions(+), 7 deletions(-) -diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h -index 72f9126d..c84b5be8 100644 ---- a/src/include/lwip/priv/tcp_priv.h -+++ b/src/include/lwip/priv/tcp_priv.h -@@ -106,14 +106,11 @@ err_t tcp_process_refused_data(struct tcp_pcb *pcb); - #define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) - - --#define TCP_SEQ_LT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0) --#define TCP_SEQ_LEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0) --#define TCP_SEQ_GT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0) --#define TCP_SEQ_GEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0) -+#define TCP_SEQ_LT(a,b) (((u32_t)((u32_t)(a) - (u32_t)(b)) & 0x80000000u) != 0) -+#define TCP_SEQ_LEQ(a,b) (!(TCP_SEQ_LT(b,a))) -+#define TCP_SEQ_GT(a,b) TCP_SEQ_LT(b,a) -+#define TCP_SEQ_GEQ(a,b) TCP_SEQ_LEQ(b,a) - /* is b<=a<=c? */ --#if 0 /* see bug #10548 */ --#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b)) --#endif - #define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c)) - - #ifndef TCP_TMR_INTERVAL --- -2.28.0.windows.1 diff --git a/backport-tcp-tighten-up-checks-for-received-SYN.patch b/backport-tcp-tighten-up-checks-for-received-SYN.patch deleted file mode 100644 index 0892cbf..0000000 --- a/backport-tcp-tighten-up-checks-for-received-SYN.patch +++ /dev/null @@ -1,58 +0,0 @@ -From adbc5b5f716d108966bcf606e61de60b83f525a5 Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Thu, 5 Mar 2020 21:20:35 +0100 -Subject: [PATCH] tcp: tighten up checks for received SYN -Any malicous segment could contain a SYN up to now (no check). -A SYN in the wrong segment could break OOSEQ queueing. -Fix this by allowing SYN only in states where it is required. -See bug #56397: Assert "tcp_receive: ooseq tcplen > rcv_wnd" -Signed-off-by: Simon Goldschmidt -Conflict: NA -Reference: https://git.savannah.gnu.org/cgit/lwip.git/commit/?id=adbc5b5f716d108966bcf606e61de60b83f525a5 ---- - src/core/tcp_in.c | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) -diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c -index 4bfba85f..90061281 100644 ---- a/src/core/tcp_in.c -+++ b/src/core/tcp_in.c -@@ -852,6 +852,13 @@ tcp_process(struct tcp_pcb *pcb) - - tcp_parseopt(pcb); - -+ if (flags & TCP_SYN) { -+ /* accept SYN only in 2 states: */ -+ if ((pcb->state != SYN_SENT) && (pcb->state != SYN_RCVD)) { -+ return ERR_OK; -+ } -+ } -+ - /* Do different things depending on the TCP state. */ - switch (pcb->state) { - case SYN_SENT: -@@ -924,7 +931,12 @@ tcp_process(struct tcp_pcb *pcb) - } - break; - case SYN_RCVD: -- if (flags & TCP_ACK) { -+ if (flags & TCP_SYN) { -+ if (seqno == pcb->rcv_nxt - 1) { -+ /* Looks like another copy of the SYN - retransmit our SYN-ACK */ -+ tcp_rexmit(pcb); -+ } -+ } else if (flags & TCP_ACK) { - /* expected ACK number? */ - if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) { - pcb->state = ESTABLISHED; -@@ -975,9 +987,6 @@ tcp_process(struct tcp_pcb *pcb) - tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(), - ip_current_src_addr(), tcphdr->dest, tcphdr->src); - } -- } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { -- /* Looks like another copy of the SYN - retransmit our SYN-ACK */ -- tcp_rexmit(pcb); - } - break; - case CLOSE_WAIT: --- -2.28.0.windows.1 diff --git a/lwip-2.1.3.zip b/lwip-2.1.3.zip deleted file mode 100644 index 9f897f7..0000000 Binary files a/lwip-2.1.3.zip and /dev/null differ diff --git a/lwip-2.2.0.zip b/lwip-2.2.0.zip new file mode 100644 index 0000000..b967956 Binary files /dev/null and b/lwip-2.2.0.zip differ diff --git a/lwip.spec b/lwip.spec index 2afc60f..20b6d2a 100644 --- a/lwip.spec +++ b/lwip.spec @@ -3,16 +3,12 @@ Summary: lwip is a small independent implementation of the TCP/IP protocol suite Name: lwip -Version: 2.1.3 -Release: 95 +Version: 2.2.0 +Release: 29 License: BSD URL: http://savannah.nongnu.org/projects/lwip/ Source0: http://download.savannah.nongnu.org/releases/lwip/%{name}-%{version}.zip - -Patch6001: backport-tcp-fix-sequence-number-comparison.patch -Patch6002: backport-tcp-tighten-up-checks-for-received-SYN.patch - Patch9000: 0001-add-makefile.patch Patch9001: 0002-adapt-lstack.patch Patch9002: 0003-fix-the-occasional-coredump-when-the-lwip-exits.patch @@ -58,7 +54,7 @@ Patch9041: 0042-expand-recv-win.patch Patch9042: 0043-add-prefetch.patch Patch9043: 0044-skip-unnecessary-tcp_route.patch Patch9044: 0045-add-variable-in-struct-sock.patch -Patch9045: 0046-add-dataack-when-recv-too-many-acks-with-data.patch + Patch9046: 0047-reduce-struct-pbuf-size.patch Patch9047: 0048-listen-pcb-also-use-pcb_if.patch Patch9048: 0049-expand-recv-mbox-size.patch @@ -91,8 +87,7 @@ Patch9074: 0075-adapt-read-write-for-rtc-mode.patch Patch9075: 0076-fix-recvmsg-return-EINVAL.patch Patch9076: 0077-adpat-event-for-rtc-mode.patch Patch9077: 0078-posix_api-support-select.patch -Patch6003: backport-Add-outgoing-VLAN-PCP-support.patch -Patch6004: backport-fix-compiling-ETHARP_SUPPORT_VLAN.patch + Patch9078: 0079-enable-vlan-define.patch Patch9079: 0080-enable-ipv6.patch Patch9080: 0081-ip6-hdr.patch @@ -107,12 +102,58 @@ Patch9088: 0089-add-struct-gz-addr.patch Patch9089: 0090-frag-fix-coredump-when-get-netif.patch Patch9090: 0091-add-fd-log-info-and-fix-wrong-port-log-info.patch Patch9091: 0092-fix-the-coredump-issue-when-UDP-traffic-is-sent.patch +Patch9092: 0093-modfiy-accept-null-pointer-when-new-conn-receive-RST-packet-in-listening.patch +Patch9093: 0094-lwip-log-fix-reversed-port-in-tcp_input.patch +Patch9094: 0095-event_callback-del-errevent-log-if-err-is-ERR_OK.patch +Patch9095: 0096-tcp_send_fin-add-the-fin-to-the-last-unsent-segment.patch +Patch9096: 0097-Mod-the-issue-that-2w-connection-unable-to-establish.patch +Patch9097: 0098-remove-duplicate-lwip-log.patch +Patch9098: 0099-fix-rte_ring_create-time-consuming.patch +Patch9099: 0100-replace-qtuple-addr-with-gz_addr_t.patch +Patch9100: 0101-fix-wrong-namelen-in-getaddrname.patch +Patch9101: 0102-dfx-add-tcp_in-empty-ack-cnt-and-del-rst-invalid-log.patch + + +Patch9102: 0103-adapt-for-dpdk-23.11.patch +Patch9103: 0104-optimize-enqueue-for-unacked-and-unsent-queue.patch +Patch9104: 0105-delete-redundant-logs-in-lwip.patch +Patch9105: 0106-remove-unnecessary-variables-in-struct-pbuf.patch +Patch9106: 0107-fix-move-lpcb-to-the-front-of-list-error.patch +Patch9107: 0108-fix-receive-fin-packet-process-error.patch +Patch9108: 0109-support-udp-recv-zero-packets.patch +Patch9109: 0110-adapt-lwip-2.2.0.patch +Patch9110: 0111-support-udp-pkglen-mtu-modify-IP_REASS_MAX_PBUFS.patch +Patch9111: 0112-support-udp-pkglen-mtu-modify-netbuf_alloc-size.patch +Patch9112: 0113-fix-duplicate-pbuf_free-in-udp_sendto.patch +Patch9113: 0114-sync-recv-flags-with-linux-kernel.patch +Patch9114: 0115-enable-LWIP_SO_RCVTIMEO-to-support-recv-accept-timeo.patch +Patch9115: 0116-transfer-pbuf-timestamp-in-ip-frag.patch +Patch9116: 0117-udp-muticast-loop.patch +Patch9117: 0118-support-querying-udp-multicast-addresses.patch +Patch9118: 0119-support-igmpv3.patch +Patch9119: 0120-enable-SO_REUSE_RXTOALL.patch +Patch9120: 0121-add-vlan-filter.patch +Patch9121: 0122-support-mldv2.patch +Patch9122: 0123-opts-modify-MEMP_NUM_UDP_PCB.patch +Patch9123: 0124-fix-udp-recv-memleak.patch +Patch9124: 0125-add-MCAST_JOIN_SOURCE_GROUP-to-setsockopt-for-mldv2.patch +Patch9125: 0126-add-stats_proto-in-out-to-xmit-recv.patch +Patch9126: 0127-add-MCAST_BLOCK_SOURCE-to-setsockopt-for-mldv2.patch +Patch9127: 0128-add-MCAST_JOIN_SOURCE_GROUP-to-setsockopt-for-igmpv3.patch +Patch9128: 0129-memset-gazelle_quintuple-in-vdev_reg_done.patch +Patch9129: 0130-add-MCAST_JOIN_GROUP-to-setsockopt-for-igmpv3.patch +Patch9130: 0131-add-MCAST_BLOCK_SOURCE-to-setsockopt-for-igmpv3.patch +Patch9131: 0132-mod-udp-loop-mem-leak.patch +Patch9132: 0133-allow-membership-to-register-multiple-times.patch +Patch9133: 0134-mod-checksum-of-ip_hdr-and-udp_hdr.patch +Patch9134: 0135-change-STAT_COUNTER-from-u16-to-u64.patch +Patch9135: 0136-fix-vlan-filter-bug.patch BuildRequires: gcc-c++ dos2unix dpdk-devel #Requires: -ExclusiveArch: x86_64 aarch64 loongarch64 sw_64 +ExclusiveArch: x86_64 aarch64 loongarch64 sw_64 riscv64 ppc64le %description lwip is a small independent implementation of the TCP/IP protocol suite. @@ -123,7 +164,6 @@ find %{_builddir}/%{name}-%{version} -type f -exec dos2unix -q {} \; %autopatch -p1 %build -export DPDK_VERSION_1911=1 cd %{_builddir}/%{name}-%{version}/src %make_build @@ -137,6 +177,157 @@ cd %{_builddir}/%{name}-%{version}/src %{_libdir}/liblwip.a %changelog +* Fri May 24 2024 zhengjiebing - 2.2.0-29 +- fix vlan filter bug + +* Tue May 21 2024 ningjin - 2.2.0-28 +- change change STAT_COUNTER from u16 to u64 + +* Thu May 09 2024 hankangkang - 2.2.0-27 +- mod checksum of ip_hdr and udp_hdr + +* Fri May 10 2024 wanfeng - 2.2.0-26 +- allow multicast membership to register multiple times + +* Tue May 07 2024 hankangkang - 2.2.0-25 +- Fix MBUF memory leakage issue when message length is greater than MTU + +* Tue May 07 2024 zhangyulong - 2.2.0-24 +- add option MCAST_BLOCK_SOURCE to the setsockopt for the igmpv3 protocol + +* Mon May 06 2024 zhangyulong - 2.2.0-23 +- add option MCAST_JOIN_GROUP to the setsockopt for the igmpv3 protocol + +* Tue Apr 30 2024 yinbin - 2.2.0-22 +- memset gazelle_quintuple in vdev_reg_done + +* Mon Apr 29 2024 zhangyulong - 2.2.0-21 +- add option MCAST_JOIN_SOURCE_GROUP to the setsockopt for the igmpv3 protocol + +* Mon Apr 29 2024 wanfeng - 2.2.0-20 +- add option MCAST_BLOCK_SOURCE to the setsockopt for the mldv2 protocol + +* Thu Apr 25 2024 ningjin - 2.2.0-19 +- add in/out and xmit/recv to stats_proto + +* Wed Apr 24 2024 wanfeng - 2.2.0-18 +- add option MCAST_JOIN_SOURCE_GROUP to the setsockopt for the mldv2 protocol + +* Mon Apr 22 2024 zhujunhao - 2.2.0-17 +- fix udp recv memleak + +* Thu Apr 11 2024 yinbin - 2.2.0-16 +- opts: modify MEMP_NUM_UDP_PCB + +* Tue Apr 09 2024 wanfeng - 2.2.0-15 +- add ipv6 mldv2 multicast protocol + +* Mon Apr 08 2024 zhengjiebing - 2.2.0-14 +- add vlan filter + +* Fri Mar 29 2024 liyunqing - 2.2.0-13 +- enable SO_REUSE_RXTOALL + +* Fri Mar 29 2024 zhangyulong - 2.2.0-12 +- add igmp v3 multicast protocol + +* Sat Mar 23 2024 wuchangye - 2.2.0-11 +- support querying udp multicast addresses + +* Fri Mar 22 2024 zhujunhao - 2.2.0-10 +- add udp muticast loop + +* Mon Mar 18 2024 yangchen - 2.2.0-9 +- tansfer pbuf timestamp in ip frag + +* Fri Mar 15 2024 liyunqing - 2.2.0-8 +- enable LWIP_SO_RCVTIMEO to support recv\accept timeout + +* Mon Mar 11 2024 liyunqing - 2.2.0-7 +- sync macros with kernel defined which use in recv and send + +* Thu Mar 7 2024 liyunqing - 2.2.0-6 +- fix duplicate pbuf_free in udp_sendto + +* Wed Mar 6 2024 yangchen - 2.2.0-5 +- support udp pkglen > mtu: modify netbuf_alloc size + +* Tue Mar 5 2024 yangchen - 2.2.0-4 +- support udp pkglen > mtu: modify IP_REASS_MAX_PBUFS + +* Tue Mar 5 2024 peng.zou - 2.2.0-3 +- add ppc64le support + +* Sun Feb 18 2024 jiangheng - 2.2.0-2 +- remove backport patches +- sys_mbox_new return error when rte ring create failed + +* Mon Feb 05 2024 jiangheng - 2.2.0-1 +- update to lwip-2.2.0 + +* Fri Feb 2 2024 shafeipaozi - 2.1.3-116 +- add support riscv + +* Thu Feb 01 2024 yangchen - 2.1.3-115 +- support udp recv zero packets + +* Tue Jan 30 2024 jiangheng - 2.1.3-114 +- fix receive fin packet process error + +* Tue Jan 30 2024 jiangheng - 2.1.3-113 +- fix move lpcb to the front of list error + +* Wed Jan 24 2024 jiangheng - 2.1.3-112 +- adapt for dpdk-23.11 + +* Fri Jan 19 2024 jiangheng - 2.1.3-111 +- remove unnecessary variables in struct pbuf + +* Wed Jan 10 2024 hankangkang - 2.1.3-110 +- delete redundant logs in lwip + +* Tue Jan 16 2024 zhengjiebing - 2.1.3-109 +- optimize enqueue way for unacked and unsent queue + +* Mon Jan 15 2024 jiangheng - 2.1.3-108 +- adapt for dpdk-23.11 + +* Wed Jan 10 2024 yangchen - 2.1.3-107 +- dfx: add tcp_in empty ack cnt and del rst invalid log + +* Mon Jan 08 2024 zhengjiebing - 2.1.3-106 +- fix wrong namelen in lwip_getaddrname + +* Tue Jan 02 2024 zhengjiebing - 2.1.3-105 +- replace qtuple addr with gz_addr_t + +* Tue Jan 02 2024 jiangheng - 2.1.3-104 +- tcp_in: fix ooseq update error + +* Fri Dec 29 2023 jiangheng - 2.1.3-103 +- rte_ring_get_memsize adapt dpdk 19.11 + +* Tue Dec 26 2023 jiangheng - 2.1.3-102 +- fix rte_ring_create/free time-consuming + +* Tue Dec 26 2023 jiangheng - 2.1.3-101 +- remove duplicate lwip log + +* Mon Dec 25 2023 hankangkang - 2.1.3-100 +- Mod the issue that 2w connection unable to establish + +* Sat Dec 23 2023 yangchen - 2.1.3-99 +- tcp_send_fin: add the fin to the last unsent segment + +* Wed Dec 20 2023 yangchen - 2.1.3-98 +- event_callback: del errevent log if err is ERR_OK + +* Fri Dec 15 2023 yangchen - 2.1.3-97 +- lwip log: fix reversed port in tcp_input + +* Thu Dec 14 2023 hankangkang - 2.1.3-96 +- modfiy-accept-null-pointer-when-new-conn-receive-RST-packet-in-listening + * Sat Dec 9 2023 wuchangye - 2.1.3-95 - fix the coredump issue when UDP traffic is sent @@ -186,10 +377,9 @@ cd %{_builddir}/%{name}-%{version}/src - adapt read/write for rtc mode - fix recvmsg return EINVAL - adapt event for rtc mode -- gazelle offloads are registerd to lwip -* Fri Nov 3 2023 liyanan - 2.1.3-79 -- Adapt dpdk fallback +* Tue Oct 24 2023 jiangheng - 2.1.3-79 +- gazelle offloads are registerd to lwip * Sun Oct 08 2023 jiangheng - 2.1.3-78 - lstack_lwip: external api start with do_lwip_ prefix