static int multi_tcp_post(struct multi_context *m, struct multi_instance *mi, const int action) { struct context *c = multi_tcp_context(m, mi); int newaction = TA_UNDEF; #define MTP_NONE 0 #define MTP_TUN_OUT (1<<0) #define MTP_LINK_OUT (1<<1) unsigned int flags = MTP_NONE; if (TUN_OUT(c)) { flags |= MTP_TUN_OUT; } if (LINK_OUT(c)) { flags |= MTP_LINK_OUT; } switch (flags) { case MTP_TUN_OUT|MTP_LINK_OUT: case MTP_TUN_OUT: newaction = TA_TUN_WRITE; break; case MTP_LINK_OUT: newaction = TA_SOCKET_WRITE; break; case MTP_NONE: if (mi && socket_read_residual(c->c2.link_socket)) { newaction = TA_SOCKET_READ_RESIDUAL; } else { multi_tcp_set_global_rw_flags(m, mi); } break; default: { struct gc_arena gc = gc_new(); msg(M_FATAL, "MULTI TCP: multi_tcp_post bad state, mi=%s flags=%d", multi_instance_string(mi, false, &gc), flags); gc_free(&gc); break; } } dmsg(D_MULTI_DEBUG, "MULTI TCP: multi_tcp_post %s -> %s", pract(action), pract(newaction)); return newaction; }
/* * Return the io_wait() flags appropriate for * a point-to-multipoint tunnel. */ static inline unsigned int p2mp_iow_flags (const struct multi_context *m) { unsigned int flags = IOW_WAIT_SIGNAL; if (m->pending) { if (TUN_OUT (&m->pending->context)) flags |= IOW_TO_TUN; if (LINK_OUT (&m->pending->context)) flags |= IOW_TO_LINK; } else if (mbuf_defined (m->mbuf)) flags |= IOW_MBUF; else flags |= IOW_READ; return flags; }